home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 10 / AACD 10.iso / AACD / Games / MAME / src / usrintrf.c < prev    next >
C/C++ Source or Header  |  2000-05-13  |  101KB  |  3,740 lines

  1. /*********************************************************************
  2.  
  3.   usrintrf.c
  4.  
  5.   Functions used to handle MAME's crude user interface.
  6.  
  7. *********************************************************************/
  8.  
  9. #include "driver.h"
  10. #include "info.h"
  11. #include "vidhrdw/vector.h"
  12. #include "datafile.h"
  13. #include <stdarg.h>
  14. #include "ui_text.h"
  15.  
  16. #ifdef MESS
  17.   #include "mess/mess.h"
  18. #endif
  19.  
  20. extern int mame_debug;
  21.  
  22. extern int bitmap_dirty;    /* set by osd_clearbitmap() */
  23.  
  24. /* Variables for stat menu */
  25. extern char build_version[];
  26. extern unsigned int dispensed_tickets;
  27. extern unsigned int coins[COIN_COUNTERS];
  28. extern unsigned int coinlockedout[COIN_COUNTERS];
  29.  
  30. /* MARTINEZ.F 990207 Memory Card */
  31. #ifndef NEOFREE
  32. #ifndef TINY_COMPILE
  33. int         memcard_menu(struct osd_bitmap *bitmap, int);
  34. extern int    mcd_action;
  35. extern int    mcd_number;
  36. extern int    memcard_status;
  37. extern int    memcard_number;
  38. extern int    memcard_manager;
  39. #endif
  40. #endif
  41.  
  42. extern int neogeo_memcard_load(int);
  43. extern void neogeo_memcard_save(void);
  44. extern void neogeo_memcard_eject(void);
  45. extern int neogeo_memcard_create(int);
  46. /* MARTINEZ.F 990207 Memory Card End */
  47.  
  48.  
  49.  
  50. static int setup_selected;
  51. static int osd_selected;
  52. static int jukebox_selected;
  53. static int single_step;
  54. static int trueorientation;
  55. static int orientation_count;
  56.  
  57.  
  58. static void switch_ui_orientation(void)
  59. {
  60.     if (orientation_count == 0)
  61.     {
  62.         trueorientation = Machine->orientation;
  63.         Machine->orientation = Machine->ui_orientation;
  64.         set_pixel_functions();
  65.     }
  66.  
  67.     orientation_count++;
  68. }
  69.  
  70. static void switch_true_orientation(void)
  71. {
  72.     orientation_count--;
  73.  
  74.     if (orientation_count == 0)
  75.     {
  76.         Machine->orientation = trueorientation;
  77.         set_pixel_functions();
  78.     }
  79. }
  80.  
  81.  
  82. void set_ui_visarea (int xmin, int ymin, int xmax, int ymax)
  83. {
  84.     int temp,w,h;
  85.  
  86.     /* special case for vectors */
  87.     if(Machine->drv->video_attributes == VIDEO_TYPE_VECTOR)
  88.     {
  89.         if (Machine->ui_orientation & ORIENTATION_SWAP_XY)
  90.         {
  91.             temp=xmin; xmin=ymin; ymin=temp;
  92.             temp=xmax; xmax=ymax; ymax=temp;
  93.         }
  94.     }
  95.     else
  96.     {
  97.         if (Machine->orientation & ORIENTATION_SWAP_XY)
  98.         {
  99.             w = Machine->drv->screen_height;
  100.             h = Machine->drv->screen_width;
  101.         }
  102.         else
  103.         {
  104.             w = Machine->drv->screen_width;
  105.             h = Machine->drv->screen_height;
  106.         }
  107.  
  108.         if (Machine->ui_orientation & ORIENTATION_FLIP_X)
  109.         {
  110.             temp = w - xmin - 1;
  111.             xmin = w - xmax - 1;
  112.             xmax = temp ;
  113.         }
  114.  
  115.         if (Machine->ui_orientation & ORIENTATION_FLIP_Y)
  116.         {
  117.             temp = h - ymin - 1;
  118.             ymin = h - ymax - 1;
  119.             ymax = temp;
  120.         }
  121.  
  122.         if (Machine->ui_orientation & ORIENTATION_SWAP_XY)
  123.         {
  124.             temp = xmin; xmin = ymin; ymin = temp;
  125.             temp = xmax; xmax = ymax; ymax = temp;
  126.         }
  127.  
  128.     }
  129.     Machine->uiwidth = xmax-xmin+1;
  130.     Machine->uiheight = ymax-ymin+1;
  131.     Machine->uixmin = xmin;
  132.     Machine->uiymin = ymin;
  133. }
  134.  
  135.  
  136.  
  137. struct GfxElement *builduifont(void)
  138. {
  139.     static unsigned char fontdata6x8[] =
  140.     {
  141.         0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  142.         0x7c,0x80,0x98,0x90,0x80,0xbc,0x80,0x7c,0xf8,0x04,0x64,0x44,0x04,0xf4,0x04,0xf8,
  143.         0x7c,0x80,0x98,0x88,0x80,0xbc,0x80,0x7c,0xf8,0x04,0x64,0x24,0x04,0xf4,0x04,0xf8,
  144.         0x7c,0x80,0x88,0x98,0x80,0xbc,0x80,0x7c,0xf8,0x04,0x24,0x64,0x04,0xf4,0x04,0xf8,
  145.         0x7c,0x80,0x90,0x98,0x80,0xbc,0x80,0x7c,0xf8,0x04,0x44,0x64,0x04,0xf4,0x04,0xf8,
  146.         0x30,0x48,0x84,0xb4,0xb4,0x84,0x48,0x30,0x30,0x48,0x84,0x84,0x84,0x84,0x48,0x30,
  147.         0x00,0xfc,0x84,0x8c,0xd4,0xa4,0xfc,0x00,0x00,0xfc,0x84,0x84,0x84,0x84,0xfc,0x00,
  148.         0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x68,0x78,0x78,0x30,0x00,0x00,
  149.         0x80,0xc0,0xe0,0xf0,0xe0,0xc0,0x80,0x00,0x04,0x0c,0x1c,0x3c,0x1c,0x0c,0x04,0x00,
  150.         0x20,0x70,0xf8,0x20,0x20,0xf8,0x70,0x20,0x48,0x48,0x48,0x48,0x48,0x00,0x48,0x00,
  151.         0x00,0x00,0x30,0x68,0x78,0x30,0x00,0x00,0x00,0x30,0x68,0x78,0x78,0x30,0x00,0x00,
  152.         0x70,0xd8,0xe8,0xe8,0xf8,0xf8,0x70,0x00,0x1c,0x7c,0x74,0x44,0x44,0x4c,0xcc,0xc0,
  153.         0x20,0x70,0xf8,0x70,0x70,0x70,0x70,0x00,0x70,0x70,0x70,0x70,0xf8,0x70,0x20,0x00,
  154.         0x00,0x10,0xf8,0xfc,0xf8,0x10,0x00,0x00,0x00,0x20,0x7c,0xfc,0x7c,0x20,0x00,0x00,
  155.         0xb0,0x54,0xb8,0xb8,0x54,0xb0,0x00,0x00,0x00,0x28,0x6c,0xfc,0x6c,0x28,0x00,0x00,
  156.         0x00,0x30,0x30,0x78,0x78,0xfc,0x00,0x00,0xfc,0x78,0x78,0x30,0x30,0x00,0x00,0x00,
  157.         0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x20,0x20,0x20,0x00,0x20,0x00,
  158.         0x50,0x50,0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x50,0xf8,0x50,0xf8,0x50,0x00,0x00,
  159.         0x20,0x70,0xc0,0x70,0x18,0xf0,0x20,0x00,0x40,0xa4,0x48,0x10,0x20,0x48,0x94,0x08,
  160.         0x60,0x90,0xa0,0x40,0xa8,0x90,0x68,0x00,0x10,0x20,0x40,0x00,0x00,0x00,0x00,0x00,
  161.         0x20,0x40,0x40,0x40,0x40,0x40,0x20,0x00,0x10,0x08,0x08,0x08,0x08,0x08,0x10,0x00,
  162.         0x20,0xa8,0x70,0xf8,0x70,0xa8,0x20,0x00,0x00,0x20,0x20,0xf8,0x20,0x20,0x00,0x00,
  163.         0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x60,0x00,0x00,0x00,0xf8,0x00,0x00,0x00,0x00,
  164.         0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x08,0x10,0x20,0x40,0x80,0x00,0x00,
  165.         0x70,0x88,0x88,0x88,0x88,0x88,0x70,0x00,0x10,0x30,0x10,0x10,0x10,0x10,0x10,0x00,
  166.         0x70,0x88,0x08,0x10,0x20,0x40,0xf8,0x00,0x70,0x88,0x08,0x30,0x08,0x88,0x70,0x00,
  167.         0x10,0x30,0x50,0x90,0xf8,0x10,0x10,0x00,0xf8,0x80,0xf0,0x08,0x08,0x88,0x70,0x00,
  168.         0x70,0x80,0xf0,0x88,0x88,0x88,0x70,0x00,0xf8,0x08,0x08,0x10,0x20,0x20,0x20,0x00,
  169.         0x70,0x88,0x88,0x70,0x88,0x88,0x70,0x00,0x70,0x88,0x88,0x88,0x78,0x08,0x70,0x00,
  170.         0x00,0x00,0x30,0x30,0x00,0x30,0x30,0x00,0x00,0x00,0x30,0x30,0x00,0x30,0x30,0x60,
  171.         0x10,0x20,0x40,0x80,0x40,0x20,0x10,0x00,0x00,0x00,0xf8,0x00,0xf8,0x00,0x00,0x00,
  172.         0x40,0x20,0x10,0x08,0x10,0x20,0x40,0x00,0x70,0x88,0x08,0x10,0x20,0x00,0x20,0x00,
  173.         0x30,0x48,0x94,0xa4,0xa4,0x94,0x48,0x30,0x70,0x88,0x88,0xf8,0x88,0x88,0x88,0x00,
  174.         0xf0,0x88,0x88,0xf0,0x88,0x88,0xf0,0x00,0x70,0x88,0x80,0x80,0x80,0x88,0x70,0x00,
  175.         0xf0,0x88,0x88,0x88,0x88,0x88,0xf0,0x00,0xf8,0x80,0x80,0xf0,0x80,0x80,0xf8,0x00,
  176.         0xf8,0x80,0x80,0xf0,0x80,0x80,0x80,0x00,0x70,0x88,0x80,0x98,0x88,0x88,0x70,0x00,
  177.         0x88,0x88,0x88,0xf8,0x88,0x88,0x88,0x00,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x00,
  178.         0x08,0x08,0x08,0x08,0x88,0x88,0x70,0x00,0x88,0x90,0xa0,0xc0,0xa0,0x90,0x88,0x00,
  179.         0x80,0x80,0x80,0x80,0x80,0x80,0xf8,0x00,0x88,0xd8,0xa8,0x88,0x88,0x88,0x88,0x00,
  180.         0x88,0xc8,0xa8,0x98,0x88,0x88,0x88,0x00,0x70,0x88,0x88,0x88,0x88,0x88,0x70,0x00,
  181.         0xf0,0x88,0x88,0xf0,0x80,0x80,0x80,0x00,0x70,0x88,0x88,0x88,0x88,0x88,0x70,0x08,
  182.         0xf0,0x88,0x88,0xf0,0x88,0x88,0x88,0x00,0x70,0x88,0x80,0x70,0x08,0x88,0x70,0x00,
  183.         0xf8,0x20,0x20,0x20,0x20,0x20,0x20,0x00,0x88,0x88,0x88,0x88,0x88,0x88,0x70,0x00,
  184.         0x88,0x88,0x88,0x88,0x88,0x50,0x20,0x00,0x88,0x88,0x88,0x88,0xa8,0xd8,0x88,0x00,
  185.         0x88,0x50,0x20,0x20,0x20,0x50,0x88,0x00,0x88,0x88,0x88,0x50,0x20,0x20,0x20,0x00,
  186.         0xf8,0x08,0x10,0x20,0x40,0x80,0xf8,0x00,0x30,0x20,0x20,0x20,0x20,0x20,0x30,0x00,
  187.         0x40,0x40,0x20,0x20,0x10,0x10,0x08,0x08,0x30,0x10,0x10,0x10,0x10,0x10,0x30,0x00,
  188.         0x20,0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,
  189.         0x40,0x20,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x70,0x08,0x78,0x88,0x78,0x00,
  190.         0x80,0x80,0xf0,0x88,0x88,0x88,0xf0,0x00,0x00,0x00,0x70,0x88,0x80,0x80,0x78,0x00,
  191.         0x08,0x08,0x78,0x88,0x88,0x88,0x78,0x00,0x00,0x00,0x70,0x88,0xf8,0x80,0x78,0x00,
  192.         0x18,0x20,0x70,0x20,0x20,0x20,0x20,0x00,0x00,0x00,0x78,0x88,0x88,0x78,0x08,0x70,
  193.         0x80,0x80,0xf0,0x88,0x88,0x88,0x88,0x00,0x20,0x00,0x20,0x20,0x20,0x20,0x20,0x00,
  194.         0x20,0x00,0x20,0x20,0x20,0x20,0x20,0xc0,0x80,0x80,0x90,0xa0,0xe0,0x90,0x88,0x00,
  195.         0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x00,0x00,0x00,0xf0,0xa8,0xa8,0xa8,0xa8,0x00,
  196.         0x00,0x00,0xb0,0xc8,0x88,0x88,0x88,0x00,0x00,0x00,0x70,0x88,0x88,0x88,0x70,0x00,
  197.         0x00,0x00,0xf0,0x88,0x88,0xf0,0x80,0x80,0x00,0x00,0x78,0x88,0x88,0x78,0x08,0x08,
  198.         0x00,0x00,0xb0,0xc8,0x80,0x80,0x80,0x00,0x00,0x00,0x78,0x80,0x70,0x08,0xf0,0x00,
  199.         0x20,0x20,0x70,0x20,0x20,0x20,0x18,0x00,0x00,0x00,0x88,0x88,0x88,0x98,0x68,0x00,
  200.         0x00,0x00,0x88,0x88,0x88,0x50,0x20,0x00,0x00,0x00,0xa8,0xa8,0xa8,0xa8,0x50,0x00,
  201.         0x00,0x00,0x88,0x50,0x20,0x50,0x88,0x00,0x00,0x00,0x88,0x88,0x88,0x78,0x08,0x70,
  202.         0x00,0x00,0xf8,0x10,0x20,0x40,0xf8,0x00,0x08,0x10,0x10,0x20,0x10,0x10,0x08,0x00,
  203.         0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x40,0x20,0x20,0x10,0x20,0x20,0x40,0x00,
  204.         0x00,0x68,0xb0,0x00,0x00,0x00,0x00,0x00,0x20,0x50,0x20,0x50,0xa8,0x50,0x00,0x00,
  205.         0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  206.         0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x40,0x0C,0x10,0x38,0x10,0x20,0x20,0xC0,0x00,
  207.         0x00,0x00,0x00,0x00,0x00,0x28,0x28,0x50,0x00,0x00,0x00,0x00,0x00,0x00,0xA8,0x00,
  208.         0x70,0xA8,0xF8,0x20,0x20,0x20,0x20,0x00,0x70,0xA8,0xF8,0x20,0x20,0xF8,0xA8,0x70,
  209.         0x20,0x50,0x88,0x00,0x00,0x00,0x00,0x00,0x44,0xA8,0x50,0x20,0x68,0xD4,0x28,0x00,
  210.         0x88,0x70,0x88,0x60,0x30,0x88,0x70,0x00,0x00,0x10,0x20,0x40,0x20,0x10,0x00,0x00,
  211.         0x78,0xA0,0xA0,0xB0,0xA0,0xA0,0x78,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  212.         0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  213.         0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x20,0x20,0x00,0x00,0x00,0x00,0x00,
  214.         0x10,0x10,0x20,0x00,0x00,0x00,0x00,0x00,0x28,0x50,0x50,0x00,0x00,0x00,0x00,0x00,
  215.         0x28,0x28,0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x78,0x78,0x30,0x00,0x00,
  216.         0x00,0x00,0x00,0x78,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFC,0x00,0x00,0x00,0x00,
  217.         0x68,0xB0,0x00,0x00,0x00,0x00,0x00,0x00,0xF4,0x5C,0x54,0x54,0x00,0x00,0x00,0x00,
  218.         0x88,0x70,0x78,0x80,0x70,0x08,0xF0,0x00,0x00,0x40,0x20,0x10,0x20,0x40,0x00,0x00,
  219.         0x00,0x00,0x70,0xA8,0xB8,0xA0,0x78,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  220.         0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x50,0x88,0x88,0x50,0x20,0x20,0x20,0x00,
  221.         0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x20,0x20,0x20,0x20,0x20,0x00,
  222.         0x00,0x20,0x70,0xA8,0xA0,0xA8,0x70,0x20,0x30,0x48,0x40,0xE0,0x40,0x48,0xF0,0x00,
  223.         0x00,0x48,0x30,0x48,0x48,0x30,0x48,0x00,0x88,0x88,0x50,0xF8,0x20,0xF8,0x20,0x00,
  224.         0x20,0x20,0x20,0x00,0x20,0x20,0x20,0x00,0x78,0x80,0x70,0x88,0x70,0x08,0xF0,0x00,
  225.         0xD8,0xD8,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x48,0x94,0xA4,0xA4,0x94,0x48,0x30,
  226.         0x60,0x10,0x70,0x90,0x70,0x00,0x00,0x00,0x00,0x28,0x50,0xA0,0x50,0x28,0x00,0x00,
  227.         0x00,0x00,0x00,0xF8,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x78,0x00,0x00,0x00,0x00,
  228.         0x30,0x48,0xB4,0xB4,0xA4,0xB4,0x48,0x30,0x7C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  229.         0x60,0x90,0x90,0x60,0x00,0x00,0x00,0x00,0x20,0x20,0xF8,0x20,0x20,0x00,0xF8,0x00,
  230.         0x60,0x90,0x20,0x40,0xF0,0x00,0x00,0x00,0x60,0x90,0x20,0x90,0x60,0x00,0x00,0x00,
  231.         0x10,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x88,0x88,0x88,0xC8,0xB0,0x80,
  232.         0x78,0xD0,0xD0,0xD0,0x50,0x50,0x50,0x00,0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x00,
  233.         0x00,0x00,0x00,0x00,0x00,0x10,0x20,0x00,0x20,0x60,0x20,0x20,0x70,0x00,0x00,0x00,
  234.         0x20,0x50,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0xA0,0x50,0x28,0x50,0xA0,0x00,0x00,
  235.         0x40,0x48,0x50,0x28,0x58,0xA8,0x38,0x08,0x40,0x48,0x50,0x28,0x44,0x98,0x20,0x3C,
  236.         0xC0,0x28,0xD0,0x28,0xD8,0xA8,0x38,0x08,0x20,0x00,0x20,0x40,0x80,0x88,0x70,0x00,
  237.         0x40,0x20,0x70,0x88,0xF8,0x88,0x88,0x00,0x10,0x20,0x70,0x88,0xF8,0x88,0x88,0x00,
  238.         0x70,0x00,0x70,0x88,0xF8,0x88,0x88,0x00,0x68,0xB0,0x70,0x88,0xF8,0x88,0x88,0x00,
  239.         0x50,0x00,0x70,0x88,0xF8,0x88,0x88,0x00,0x20,0x50,0x70,0x88,0xF8,0x88,0x88,0x00,
  240.         0x78,0xA0,0xA0,0xF0,0xA0,0xA0,0xB8,0x00,0x70,0x88,0x80,0x80,0x88,0x70,0x08,0x70,
  241.         0x40,0x20,0xF8,0x80,0xF0,0x80,0xF8,0x00,0x10,0x20,0xF8,0x80,0xF0,0x80,0xF8,0x00,
  242.         0x70,0x00,0xF8,0x80,0xF0,0x80,0xF8,0x00,0x50,0x00,0xF8,0x80,0xF0,0x80,0xF8,0x00,
  243.         0x40,0x20,0x70,0x20,0x20,0x20,0x70,0x00,0x10,0x20,0x70,0x20,0x20,0x20,0x70,0x00,
  244.         0x70,0x00,0x70,0x20,0x20,0x20,0x70,0x00,0x50,0x00,0x70,0x20,0x20,0x20,0x70,0x00,
  245.         0x70,0x48,0x48,0xE8,0x48,0x48,0x70,0x00,0x68,0xB0,0x88,0xC8,0xA8,0x98,0x88,0x00,
  246.         0x40,0x20,0x70,0x88,0x88,0x88,0x70,0x00,0x10,0x20,0x70,0x88,0x88,0x88,0x70,0x00,
  247.         0x70,0x00,0x70,0x88,0x88,0x88,0x70,0x00,0x68,0xB0,0x70,0x88,0x88,0x88,0x70,0x00,
  248.         0x50,0x00,0x70,0x88,0x88,0x88,0x70,0x00,0x00,0x88,0x50,0x20,0x50,0x88,0x00,0x00,
  249.         0x00,0x74,0x88,0x90,0xA8,0x48,0xB0,0x00,0x40,0x20,0x88,0x88,0x88,0x88,0x70,0x00,
  250.         0x10,0x20,0x88,0x88,0x88,0x88,0x70,0x00,0x70,0x00,0x88,0x88,0x88,0x88,0x70,0x00,
  251.         0x50,0x00,0x88,0x88,0x88,0x88,0x70,0x00,0x10,0xA8,0x88,0x50,0x20,0x20,0x20,0x00,
  252.         0x00,0x80,0xF0,0x88,0x88,0xF0,0x80,0x80,0x60,0x90,0x90,0xB0,0x88,0x88,0xB0,0x00,
  253.         0x40,0x20,0x70,0x08,0x78,0x88,0x78,0x00,0x10,0x20,0x70,0x08,0x78,0x88,0x78,0x00,
  254.         0x70,0x00,0x70,0x08,0x78,0x88,0x78,0x00,0x68,0xB0,0x70,0x08,0x78,0x88,0x78,0x00,
  255.         0x50,0x00,0x70,0x08,0x78,0x88,0x78,0x00,0x20,0x50,0x70,0x08,0x78,0x88,0x78,0x00,
  256.         0x00,0x00,0xF0,0x28,0x78,0xA0,0x78,0x00,0x00,0x00,0x70,0x88,0x80,0x78,0x08,0x70,
  257.         0x40,0x20,0x70,0x88,0xF8,0x80,0x70,0x00,0x10,0x20,0x70,0x88,0xF8,0x80,0x70,0x00,
  258.         0x70,0x00,0x70,0x88,0xF8,0x80,0x70,0x00,0x50,0x00,0x70,0x88,0xF8,0x80,0x70,0x00,
  259.         0x40,0x20,0x00,0x60,0x20,0x20,0x70,0x00,0x10,0x20,0x00,0x60,0x20,0x20,0x70,0x00,
  260.         0x20,0x50,0x00,0x60,0x20,0x20,0x70,0x00,0x50,0x00,0x00,0x60,0x20,0x20,0x70,0x00,
  261.         0x50,0x60,0x10,0x78,0x88,0x88,0x70,0x00,0x68,0xB0,0x00,0xF0,0x88,0x88,0x88,0x00,
  262.         0x40,0x20,0x00,0x70,0x88,0x88,0x70,0x00,0x10,0x20,0x00,0x70,0x88,0x88,0x70,0x00,
  263.         0x20,0x50,0x00,0x70,0x88,0x88,0x70,0x00,0x68,0xB0,0x00,0x70,0x88,0x88,0x70,0x00,
  264.         0x00,0x50,0x00,0x70,0x88,0x88,0x70,0x00,0x00,0x20,0x00,0xF8,0x00,0x20,0x00,0x00,
  265.         0x00,0x00,0x68,0x90,0xA8,0x48,0xB0,0x00,0x40,0x20,0x88,0x88,0x88,0x98,0x68,0x00,
  266.         0x10,0x20,0x88,0x88,0x88,0x98,0x68,0x00,0x70,0x00,0x88,0x88,0x88,0x98,0x68,0x00,
  267.         0x50,0x00,0x88,0x88,0x88,0x98,0x68,0x00,0x10,0x20,0x88,0x88,0x88,0x78,0x08,0x70,
  268.         0x80,0xF0,0x88,0x88,0xF0,0x80,0x80,0x80,0x50,0x00,0x88,0x88,0x88,0x78,0x08,0x70
  269.     };
  270. #if 0
  271.     static unsigned char fontdata6x8[] =
  272.     {
  273.         0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  274.         0x7c,0x80,0x98,0x90,0x80,0xbc,0x80,0x7c,0xf8,0x04,0x64,0x44,0x04,0xf4,0x04,0xf8,
  275.         0x7c,0x80,0x98,0x88,0x80,0xbc,0x80,0x7c,0xf8,0x04,0x64,0x24,0x04,0xf4,0x04,0xf8,
  276.         0x7c,0x80,0x88,0x98,0x80,0xbc,0x80,0x7c,0xf8,0x04,0x24,0x64,0x04,0xf4,0x04,0xf8,
  277.         0x7c,0x80,0x90,0x98,0x80,0xbc,0x80,0x7c,0xf8,0x04,0x44,0x64,0x04,0xf4,0x04,0xf8,
  278.         0x30,0x48,0x84,0xb4,0xb4,0x84,0x48,0x30,0x30,0x48,0x84,0x84,0x84,0x84,0x48,0x30,
  279.         0x00,0xfc,0x84,0x8c,0xd4,0xa4,0xfc,0x00,0x00,0xfc,0x84,0x84,0x84,0x84,0xfc,0x00,
  280.         0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x68,0x78,0x78,0x30,0x00,0x00,
  281.         0x80,0xc0,0xe0,0xf0,0xe0,0xc0,0x80,0x00,0x04,0x0c,0x1c,0x3c,0x1c,0x0c,0x04,0x00,
  282.         0x20,0x70,0xf8,0x20,0x20,0xf8,0x70,0x20,0x48,0x48,0x48,0x48,0x48,0x00,0x48,0x00,
  283.         0x00,0x00,0x30,0x68,0x78,0x30,0x00,0x00,0x00,0x30,0x68,0x78,0x78,0x30,0x00,0x00,
  284.         0x70,0xd8,0xe8,0xe8,0xf8,0xf8,0x70,0x00,0x1c,0x7c,0x74,0x44,0x44,0x4c,0xcc,0xc0,
  285.         0x20,0x70,0xf8,0x70,0x70,0x70,0x70,0x00,0x70,0x70,0x70,0x70,0xf8,0x70,0x20,0x00,
  286.         0x00,0x10,0xf8,0xfc,0xf8,0x10,0x00,0x00,0x00,0x20,0x7c,0xfc,0x7c,0x20,0x00,0x00,
  287.         0xb0,0x54,0xb8,0xb8,0x54,0xb0,0x00,0x00,0x00,0x28,0x6c,0xfc,0x6c,0x28,0x00,0x00,
  288.         0x00,0x30,0x30,0x78,0x78,0xfc,0x00,0x00,0xfc,0x78,0x78,0x30,0x30,0x00,0x00,0x00,
  289.         0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x20,0x20,0x20,0x00,0x20,0x00,
  290.         0x50,0x50,0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x50,0xf8,0x50,0xf8,0x50,0x00,0x00,
  291.         0x20,0x70,0xc0,0x70,0x18,0xf0,0x20,0x00,0x40,0xa4,0x48,0x10,0x20,0x48,0x94,0x08,
  292.         0x60,0x90,0xa0,0x40,0xa8,0x90,0x68,0x00,0x10,0x20,0x40,0x00,0x00,0x00,0x00,0x00,
  293.         0x20,0x40,0x40,0x40,0x40,0x40,0x20,0x00,0x10,0x08,0x08,0x08,0x08,0x08,0x10,0x00,
  294.         0x20,0xa8,0x70,0xf8,0x70,0xa8,0x20,0x00,0x00,0x20,0x20,0xf8,0x20,0x20,0x00,0x00,
  295.         0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x60,0x00,0x00,0x00,0xf8,0x00,0x00,0x00,0x00,
  296.         0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x08,0x10,0x20,0x40,0x80,0x00,0x00,
  297.         0x70,0x88,0x88,0x88,0x88,0x88,0x70,0x00,0x10,0x30,0x10,0x10,0x10,0x10,0x10,0x00,
  298.         0x70,0x88,0x08,0x10,0x20,0x40,0xf8,0x00,0x70,0x88,0x08,0x30,0x08,0x88,0x70,0x00,
  299.         0x10,0x30,0x50,0x90,0xf8,0x10,0x10,0x00,0xf8,0x80,0xf0,0x08,0x08,0x88,0x70,0x00,
  300.         0x70,0x80,0xf0,0x88,0x88,0x88,0x70,0x00,0xf8,0x08,0x08,0x10,0x20,0x20,0x20,0x00,
  301.         0x70,0x88,0x88,0x70,0x88,0x88,0x70,0x00,0x70,0x88,0x88,0x88,0x78,0x08,0x70,0x00,
  302.         0x00,0x00,0x30,0x30,0x00,0x30,0x30,0x00,0x00,0x00,0x30,0x30,0x00,0x30,0x30,0x60,
  303.         0x10,0x20,0x40,0x80,0x40,0x20,0x10,0x00,0x00,0x00,0xf8,0x00,0xf8,0x00,0x00,0x00,
  304.         0x40,0x20,0x10,0x08,0x10,0x20,0x40,0x00,0x70,0x88,0x08,0x10,0x20,0x00,0x20,0x00,
  305.         0x30,0x48,0x94,0xa4,0xa4,0x94,0x48,0x30,0x70,0x88,0x88,0xf8,0x88,0x88,0x88,0x00,
  306.         0xf0,0x88,0x88,0xf0,0x88,0x88,0xf0,0x00,0x70,0x88,0x80,0x80,0x80,0x88,0x70,0x00,
  307.         0xf0,0x88,0x88,0x88,0x88,0x88,0xf0,0x00,0xf8,0x80,0x80,0xf0,0x80,0x80,0xf8,0x00,
  308.         0xf8,0x80,0x80,0xf0,0x80,0x80,0x80,0x00,0x70,0x88,0x80,0x98,0x88,0x88,0x70,0x00,
  309.         0x88,0x88,0x88,0xf8,0x88,0x88,0x88,0x00,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x00,
  310.         0x08,0x08,0x08,0x08,0x88,0x88,0x70,0x00,0x88,0x90,0xa0,0xc0,0xa0,0x90,0x88,0x00,
  311.         0x80,0x80,0x80,0x80,0x80,0x80,0xf8,0x00,0x88,0xd8,0xa8,0x88,0x88,0x88,0x88,0x00,
  312.         0x88,0xc8,0xa8,0x98,0x88,0x88,0x88,0x00,0x70,0x88,0x88,0x88,0x88,0x88,0x70,0x00,
  313.         0xf0,0x88,0x88,0xf0,0x80,0x80,0x80,0x00,0x70,0x88,0x88,0x88,0x88,0x88,0x70,0x08,
  314.         0xf0,0x88,0x88,0xf0,0x88,0x88,0x88,0x00,0x70,0x88,0x80,0x70,0x08,0x88,0x70,0x00,
  315.         0xf8,0x20,0x20,0x20,0x20,0x20,0x20,0x00,0x88,0x88,0x88,0x88,0x88,0x88,0x70,0x00,
  316.         0x88,0x88,0x88,0x88,0x88,0x50,0x20,0x00,0x88,0x88,0x88,0x88,0xa8,0xd8,0x88,0x00,
  317.         0x88,0x50,0x20,0x20,0x20,0x50,0x88,0x00,0x88,0x88,0x88,0x50,0x20,0x20,0x20,0x00,
  318.         0xf8,0x08,0x10,0x20,0x40,0x80,0xf8,0x00,0x30,0x20,0x20,0x20,0x20,0x20,0x30,0x00,
  319.         0x40,0x40,0x20,0x20,0x10,0x10,0x08,0x08,0x30,0x10,0x10,0x10,0x10,0x10,0x30,0x00,
  320.         0x20,0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,
  321.         0x40,0x20,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x70,0x08,0x78,0x88,0x78,0x00,
  322.         0x80,0x80,0xf0,0x88,0x88,0x88,0xf0,0x00,0x00,0x00,0x70,0x88,0x80,0x80,0x78,0x00,
  323.         0x08,0x08,0x78,0x88,0x88,0x88,0x78,0x00,0x00,0x00,0x70,0x88,0xf8,0x80,0x78,0x00,
  324.         0x18,0x20,0x70,0x20,0x20,0x20,0x20,0x00,0x00,0x00,0x78,0x88,0x88,0x78,0x08,0x70,
  325.         0x80,0x80,0xf0,0x88,0x88,0x88,0x88,0x00,0x20,0x00,0x20,0x20,0x20,0x20,0x20,0x00,
  326.         0x20,0x00,0x20,0x20,0x20,0x20,0x20,0xc0,0x80,0x80,0x90,0xa0,0xe0,0x90,0x88,0x00,
  327.         0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x00,0x00,0x00,0xf0,0xa8,0xa8,0xa8,0xa8,0x00,
  328.         0x00,0x00,0xb0,0xc8,0x88,0x88,0x88,0x00,0x00,0x00,0x70,0x88,0x88,0x88,0x70,0x00,
  329.         0x00,0x00,0xf0,0x88,0x88,0xf0,0x80,0x80,0x00,0x00,0x78,0x88,0x88,0x78,0x08,0x08,
  330.         0x00,0x00,0xb0,0xc8,0x80,0x80,0x80,0x00,0x00,0x00,0x78,0x80,0x70,0x08,0xf0,0x00,
  331.         0x20,0x20,0x70,0x20,0x20,0x20,0x18,0x00,0x00,0x00,0x88,0x88,0x88,0x98,0x68,0x00,
  332.         0x00,0x00,0x88,0x88,0x88,0x50,0x20,0x00,0x00,0x00,0xa8,0xa8,0xa8,0xa8,0x50,0x00,
  333.         0x00,0x00,0x88,0x50,0x20,0x50,0x88,0x00,0x00,0x00,0x88,0x88,0x88,0x78,0x08,0x70,
  334.         0x00,0x00,0xf8,0x10,0x20,0x40,0xf8,0x00,0x08,0x10,0x10,0x20,0x10,0x10,0x08,0x00,
  335.         0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x40,0x20,0x20,0x10,0x20,0x20,0x40,0x00,
  336.         0x00,0x68,0xb0,0x00,0x00,0x00,0x00,0x00,0x20,0x50,0x20,0x50,0xa8,0x50,0x00,0x00,
  337.     };
  338. #endif
  339.  
  340.     static struct GfxLayout fontlayout6x8 =
  341.     {
  342.         6,8,    /* 6*8 characters */
  343.         256,    /* 256 characters */
  344.         1,    /* 1 bit per pixel */
  345.         { 0 },
  346.         { 0, 1, 2, 3, 4, 5, 6, 7 }, /* straightforward layout */
  347.         { 0*8, 1*8, 2*8, 3*8, 4*8, 5*8, 6*8, 7*8 },
  348.         8*8 /* every char takes 8 consecutive bytes */
  349.     };
  350.     static struct GfxLayout fontlayout12x8 =
  351.     {
  352.         12,8,    /* 12*8 characters */
  353.         256,    /* 256 characters */
  354.         1,    /* 1 bit per pixel */
  355.         { 0 },
  356.         { 0,0, 1,1, 2,2, 3,3, 4,4, 5,5, 6,6, 7,7 }, /* straightforward layout */
  357.         { 0*8, 1*8, 2*8, 3*8, 4*8, 5*8, 6*8, 7*8 },
  358.         8*8 /* every char takes 8 consecutive bytes */
  359.     };
  360.     static struct GfxLayout fontlayout12x16 =
  361.     {
  362.         12,16,    /* 6*8 characters */
  363.         256,    /* 256 characters */
  364.         1,    /* 1 bit per pixel */
  365.         { 0 },
  366.         { 0,0, 1,1, 2,2, 3,3, 4,4, 5,5, 6,6, 7,7 }, /* straightforward layout */
  367.         { 0*8,0*8, 1*8,1*8, 2*8,2*8, 3*8,3*8, 4*8,4*8, 5*8,5*8, 6*8,6*8, 7*8,7*8 },
  368.         8*8 /* every char takes 8 consecutive bytes */
  369.     };
  370.  
  371.     struct GfxElement *font;
  372.     static unsigned short colortable[2*2];    /* ASG 980209 */
  373.  
  374.  
  375.     switch_ui_orientation();
  376.  
  377.     if ((Machine->drv->video_attributes & VIDEO_PIXEL_ASPECT_RATIO_MASK)
  378.             == VIDEO_PIXEL_ASPECT_RATIO_1_2)
  379.     {
  380.         font = decodegfx(fontdata6x8,&fontlayout12x8);
  381.         Machine->uifontwidth = 12;
  382.         Machine->uifontheight = 8;
  383.     }
  384.     else if (Machine->uiwidth >= 420 && Machine->uiheight >= 420)
  385.     {
  386.         font = decodegfx(fontdata6x8,&fontlayout12x16);
  387.         Machine->uifontwidth = 12;
  388.         Machine->uifontheight = 16;
  389.     }
  390.     else
  391.     {
  392.         font = decodegfx(fontdata6x8,&fontlayout6x8);
  393.         Machine->uifontwidth = 6;
  394.         Machine->uifontheight = 8;
  395.     }
  396.  
  397.     if (font)
  398.     {
  399.         /* colortable will be set at run time */
  400.         memset(colortable,0,sizeof(colortable));
  401.         font->colortable = colortable;
  402.         font->total_colors = 2;
  403.     }
  404.  
  405.     switch_true_orientation();
  406.  
  407.     return font;
  408. }
  409.  
  410.  
  411.  
  412. /***************************************************************************
  413.  
  414.   Display text on the screen. If erase is 0, it superimposes the text on
  415.   the last frame displayed.
  416.  
  417. ***************************************************************************/
  418.  
  419. void displaytext(struct osd_bitmap *bitmap,const struct DisplayText *dt,int erase,int update_screen)
  420. {
  421.     if (erase)
  422.         osd_clearbitmap(bitmap);
  423.  
  424.  
  425.     switch_ui_orientation();
  426.  
  427.     osd_mark_dirty (0,0,Machine->uiwidth-1,Machine->uiheight-1,1);    /* ASG 971011 */
  428.  
  429.     while (dt->text)
  430.     {
  431.         int x,y;
  432.         const char *c;
  433.  
  434.  
  435.         x = dt->x;
  436.         y = dt->y;
  437.         c = dt->text;
  438.  
  439.         while (*c)
  440.         {
  441.             int wrapped;
  442.  
  443.  
  444.             wrapped = 0;
  445.  
  446.             if (*c == '\n')
  447.             {
  448.                 x = dt->x;
  449.                 y += Machine->uifontheight + 1;
  450.                 wrapped = 1;
  451.             }
  452.             else if (*c == ' ')
  453.             {
  454.                 /* don't try to word wrap at the beginning of a line (this would cause */
  455.                 /* an endless loop if a word is longer than a line) */
  456.                 if (x != dt->x)
  457.                 {
  458.                     int nextlen=0;
  459.                     const char *nc;
  460.  
  461.  
  462.                     nc = c+1;
  463.                     while (*nc && *nc != ' ' && *nc != '\n')
  464.                     {
  465.                         nextlen += Machine->uifontwidth;
  466.                         nc++;
  467.                     }
  468.  
  469.                     /* word wrap */
  470.                     if (x + Machine->uifontwidth + nextlen > Machine->uiwidth)
  471.                     {
  472.                         x = dt->x;
  473.                         y += Machine->uifontheight + 1;
  474.                         wrapped = 1;
  475.                     }
  476.                 }
  477.             }
  478.  
  479.             if (!wrapped)
  480.             {
  481.                 drawgfx(bitmap,Machine->uifont,*c,dt->color,0,0,x+Machine->uixmin,y+Machine->uiymin,0,TRANSPARENCY_NONE,0);
  482.                 x += Machine->uifontwidth;
  483.             }
  484.  
  485.             c++;
  486.         }
  487.  
  488.         dt++;
  489.     }
  490.  
  491.     switch_true_orientation();
  492.  
  493.     if (update_screen) update_video_and_audio();
  494. }
  495.  
  496. /* Writes messages on the screen. */
  497. static void ui_text_ex(struct osd_bitmap *bitmap,const char* buf_begin, const char* buf_end, int x, int y, int color)
  498. {
  499.     switch_ui_orientation();
  500.  
  501.     for (;buf_begin != buf_end; ++buf_begin)
  502.     {
  503.         drawgfx(bitmap,Machine->uifont,*buf_begin,color,0,0,
  504.                 x + Machine->uixmin,
  505.                 y + Machine->uiymin, 0,TRANSPARENCY_NONE,0);
  506.         x += Machine->uifontwidth;
  507.     }
  508.  
  509.     switch_true_orientation();
  510. }
  511.  
  512. /* Writes messages on the screen. */
  513. void ui_text(struct osd_bitmap *bitmap,const char *buf,int x,int y)
  514. {
  515.     ui_text_ex(bitmap, buf, buf + strlen(buf), x, y, UI_COLOR_NORMAL);
  516. }
  517.  
  518. INLINE void drawhline(struct osd_bitmap *bitmap, int x, int w, int y, unsigned short color)
  519. {
  520.     int i;
  521.  
  522.     for (i = 0; i < w; i++)  plot_pixel(bitmap, x+i, y, color);
  523. }
  524.  
  525. INLINE void drawvline(struct osd_bitmap *bitmap, int x, int y, int h, unsigned short color)
  526. {
  527.     int i;
  528.  
  529.     for (i = 0; i < h; i++)  plot_pixel(bitmap, x, y+i, color);
  530. }
  531.  
  532.  
  533. void ui_drawbox(struct osd_bitmap *bitmap,int leftx,int topy,int width,int height)
  534. {
  535.     int y;
  536.     unsigned short black,white;
  537.  
  538.  
  539.     switch_ui_orientation();
  540.  
  541.     if (leftx < 0) leftx = 0;
  542.     if (topy < 0) topy = 0;
  543.     if (width > Machine->uiwidth) width = Machine->uiwidth;
  544.     if (height > Machine->uiheight) height = Machine->uiheight;
  545.  
  546.     leftx += Machine->uixmin;
  547.     topy += Machine->uiymin;
  548.  
  549.     black = Machine->uifont->colortable[0];
  550.     white = Machine->uifont->colortable[1];
  551.  
  552.     drawhline(bitmap,leftx,width,topy,         white);
  553.     drawhline(bitmap,leftx,width,topy+height-1,white);
  554.     drawvline(bitmap,leftx,        topy,height,white);
  555.     drawvline(bitmap,leftx+width-1,topy,height,white);
  556.     for (y = topy+1;y < topy+height-1;y++)
  557.         drawhline(bitmap,leftx+1,width-2,y,black);
  558.  
  559.     switch_true_orientation();
  560. }
  561.  
  562.  
  563. static void drawbar(struct osd_bitmap *bitmap,int leftx,int topy,int width,int height,int percentage,int default_percentage)
  564. {
  565.     int y;
  566.     unsigned short black,white;
  567.  
  568.  
  569.     switch_ui_orientation();
  570.  
  571.     if (leftx < 0) leftx = 0;
  572.     if (topy < 0) topy = 0;
  573.     if (width > Machine->uiwidth) width = Machine->uiwidth;
  574.     if (height > Machine->uiheight) height = Machine->uiheight;
  575.  
  576.     leftx += Machine->uixmin;
  577.     topy += Machine->uiymin;
  578.  
  579.     black = Machine->uifont->colortable[0];
  580.     white = Machine->uifont->colortable[1];
  581.  
  582.     for (y = topy;y < topy + height/8;y++)
  583.         plot_pixel(bitmap,leftx+(width-1)*default_percentage/100, y, white);
  584.  
  585.     drawhline(bitmap,leftx,width,topy+height/8,white);
  586.  
  587.     for (y = topy+height/8;y < topy+height-height/8;y++)
  588.         drawhline(bitmap,leftx,1+(width-1)*percentage/100,y,white);
  589.  
  590.     drawhline(bitmap,leftx,width,topy+height-height/8-1,white);
  591.  
  592.     for (y = topy+height-height/8;y < topy + height;y++)
  593.         plot_pixel(bitmap,leftx+(width-1)*default_percentage/100, y, white);
  594.  
  595.     switch_true_orientation();
  596. }
  597.  
  598. /* Extract one line from a multiline buffer */
  599. /* Return the characters number of the line, pbegin point to the start of the next line */
  600. static unsigned multiline_extract(const char** pbegin, const char* end, unsigned max)
  601. {
  602.     unsigned mac = 0;
  603.     const char* begin = *pbegin;
  604.     while (begin != end && mac < max)
  605.     {
  606.         if (*begin == '\n')
  607.         {
  608.             *pbegin = begin + 1; /* strip final space */
  609.             return mac;
  610.         }
  611.         else if (*begin == ' ')
  612.         {
  613.             const char* word_end = begin + 1;
  614.             while (word_end != end && *word_end != ' ' && *word_end != '\n')
  615.                 ++word_end;
  616.             if (mac + word_end - begin > max)
  617.             {
  618.                 if (mac)
  619.                 {
  620.                     *pbegin = begin + 1;
  621.                     return mac; /* strip final space */
  622.                 } else {
  623.                     *pbegin = begin + max;
  624.                     return max;
  625.                 }
  626.             }
  627.             mac += word_end - begin;
  628.             begin = word_end;
  629.         } else {
  630.             ++mac;
  631.             ++begin;
  632.         }
  633.     }
  634.     if (begin != end && (*begin == '\n' || *begin == ' '))
  635.         ++begin;
  636.     *pbegin = begin;
  637.     return mac;
  638. }
  639.  
  640. /* Compute the output size of a multiline string */
  641. static void multiline_size(int* dx, int* dy, const char* begin, const char* end, unsigned max)
  642. {
  643.     unsigned rows = 0;
  644.     unsigned cols = 0;
  645.     while (begin != end)
  646.     {
  647.         unsigned len;
  648.         len = multiline_extract(&begin,end,max);
  649.         if (len > cols)
  650.             cols = len;
  651.         ++rows;
  652.     }
  653.     *dx = cols * Machine->uifontwidth;
  654.     *dy = (rows-1) * 3*Machine->uifontheight/2 + Machine->uifontheight;
  655. }
  656.  
  657. /* Compute the output size of a multiline string with box */
  658. static void multilinebox_size(int* dx, int* dy, const char* begin, const char* end, unsigned max)
  659. {
  660.     multiline_size(dx,dy,begin,end,max);
  661.     *dx += Machine->uifontwidth;
  662.     *dy += Machine->uifontheight;
  663. }
  664.  
  665. /* Display a multiline string */
  666. static void ui_multitext_ex(struct osd_bitmap *bitmap, const char* begin, const char* end, unsigned max, int x, int y, int color)
  667. {
  668.     while (begin != end)
  669.     {
  670.         const char* line_begin = begin;
  671.         unsigned len = multiline_extract(&begin,end,max);
  672.         ui_text_ex(bitmap, line_begin, line_begin + len,x,y,color);
  673.         y += 3*Machine->uifontheight/2;
  674.     }
  675. }
  676.  
  677. /* Display a multiline string with box */
  678. static void ui_multitextbox_ex(struct osd_bitmap *bitmap,const char* begin, const char* end, unsigned max, int x, int y, int dx, int dy, int color)
  679. {
  680.     ui_drawbox(bitmap,x,y,dx,dy);
  681.     x += Machine->uifontwidth/2;
  682.     y += Machine->uifontheight/2;
  683.     ui_multitext_ex(bitmap,begin,end,max,x,y,color);
  684. }
  685.  
  686. void ui_displaymenu(struct osd_bitmap *bitmap,const char **items,const char **subitems,char *flag,int selected,int arrowize_subitem)
  687. {
  688.     struct DisplayText dt[256];
  689.     int curr_dt;
  690.     const char *lefthilight = ui_getstring (UI_lefthilight);
  691.     const char *righthilight = ui_getstring (UI_righthilight);
  692.     const char *uparrow = ui_getstring (UI_uparrow);
  693.     const char *downarrow = ui_getstring (UI_downarrow);
  694.     const char *leftarrow = ui_getstring (UI_leftarrow);
  695.     const char *rightarrow = ui_getstring (UI_rightarrow);
  696.     int i,count,len,maxlen,highlen;
  697.     int leftoffs,topoffs,visible,topitem;
  698.     int selected_long;
  699.  
  700.  
  701.     i = 0;
  702.     maxlen = 0;
  703.     highlen = Machine->uiwidth / Machine->uifontwidth;
  704.     while (items[i])
  705.     {
  706.         len = 3 + strlen(items[i]);
  707.         if (subitems && subitems[i])
  708.             len += 2 + strlen(subitems[i]);
  709.         if (len > maxlen && len <= highlen)
  710.             maxlen = len;
  711.         i++;
  712.     }
  713.     count = i;
  714.  
  715.     visible = Machine->uiheight / (3 * Machine->uifontheight / 2) - 1;
  716.     topitem = 0;
  717.     if (visible > count) visible = count;
  718.     else
  719.     {
  720.         topitem = selected - visible / 2;
  721.         if (topitem < 0) topitem = 0;
  722.         if (topitem > count - visible) topitem = count - visible;
  723.     }
  724.  
  725.     leftoffs = (Machine->uiwidth - maxlen * Machine->uifontwidth) / 2;
  726.     topoffs = (Machine->uiheight - (3 * visible + 1) * Machine->uifontheight / 2) / 2;
  727.  
  728.     /* black background */
  729.     ui_drawbox(bitmap,leftoffs,topoffs,maxlen * Machine->uifontwidth,(3 * visible + 1) * Machine->uifontheight / 2);
  730.  
  731.     selected_long = 0;
  732.     curr_dt = 0;
  733.     for (i = 0;i < visible;i++)
  734.     {
  735.         int item = i + topitem;
  736.  
  737.         if (i == 0 && item > 0)
  738.         {
  739.             dt[curr_dt].text = uparrow;
  740.             dt[curr_dt].color = UI_COLOR_NORMAL;
  741.             dt[curr_dt].x = (Machine->uiwidth - Machine->uifontwidth * strlen(uparrow)) / 2;
  742.             dt[curr_dt].y = topoffs + (3*i+1)*Machine->uifontheight/2;
  743.             curr_dt++;
  744.         }
  745.         else if (i == visible - 1 && item < count - 1)
  746.         {
  747.             dt[curr_dt].text = downarrow;
  748.             dt[curr_dt].color = UI_COLOR_NORMAL;
  749.             dt[curr_dt].x = (Machine->uiwidth - Machine->uifontwidth * strlen(downarrow)) / 2;
  750.             dt[curr_dt].y = topoffs + (3*i+1)*Machine->uifontheight/2;
  751.             curr_dt++;
  752.         }
  753.         else
  754.         {
  755.             if (subitems && subitems[item])
  756.             {
  757.                 int sublen;
  758.                 len = strlen(items[item]);
  759.                 dt[curr_dt].text = items[item];
  760.                 dt[curr_dt].color = UI_COLOR_NORMAL;
  761.                 dt[curr_dt].x = leftoffs + 3*Machine->uifontwidth/2;
  762.                 dt[curr_dt].y = topoffs + (3*i+1)*Machine->uifontheight/2;
  763.                 curr_dt++;
  764.                 sublen = strlen(subitems[item]);
  765.                 if (sublen > maxlen-5-len)
  766.                 {
  767.                     dt[curr_dt].text = "...";
  768.                     sublen = strlen(dt[curr_dt].text);
  769.                     if (item == selected)
  770.                         selected_long = 1;
  771.                 } else {
  772.                     dt[curr_dt].text = subitems[item];
  773.                 }
  774.                 /* If this item is flagged, draw it in inverse print */
  775.                 dt[curr_dt].color = (flag && flag[item]) ? UI_COLOR_INVERSE : UI_COLOR_NORMAL;
  776.                 dt[curr_dt].x = leftoffs + Machine->uifontwidth * (maxlen-1-sublen) - Machine->uifontwidth/2;
  777.                 dt[curr_dt].y = topoffs + (3*i+1)*Machine->uifontheight/2;
  778.                 curr_dt++;
  779.             }
  780.             else
  781.             {
  782.                 dt[curr_dt].text = items[item];
  783.                 dt[curr_dt].color = UI_COLOR_NORMAL;
  784.                 dt[curr_dt].x = (Machine->uiwidth - Machine->uifontwidth * strlen(items[item])) / 2;
  785.                 dt[curr_dt].y = topoffs + (3*i+1)*Machine->uifontheight/2;
  786.                 curr_dt++;
  787.             }
  788.         }
  789.     }
  790.  
  791.     i = selected - topitem;
  792.     if (subitems && subitems[selected] && arrowize_subitem)
  793.     {
  794.         if (arrowize_subitem & 1)
  795.         {
  796.             dt[curr_dt].text = leftarrow;
  797.             dt[curr_dt].color = UI_COLOR_NORMAL;
  798.             dt[curr_dt].x = leftoffs + Machine->uifontwidth * (maxlen-2 - strlen(subitems[selected])) - Machine->uifontwidth/2 - 1;
  799.             dt[curr_dt].y = topoffs + (3*i+1)*Machine->uifontheight/2;
  800.             curr_dt++;
  801.         }
  802.         if (arrowize_subitem & 2)
  803.         {
  804.             dt[curr_dt].text = rightarrow;
  805.             dt[curr_dt].color = UI_COLOR_NORMAL;
  806.             dt[curr_dt].x = leftoffs + Machine->uifontwidth * (maxlen-1) - Machine->uifontwidth/2;
  807.             dt[curr_dt].y = topoffs + (3*i+1)*Machine->uifontheight/2;
  808.             curr_dt++;
  809.         }
  810.     }
  811.     else
  812.     {
  813.         dt[curr_dt].text = righthilight;
  814.         dt[curr_dt].color = UI_COLOR_NORMAL;
  815.         dt[curr_dt].x = leftoffs + Machine->uifontwidth * (maxlen-1) - Machine->uifontwidth/2;
  816.         dt[curr_dt].y = topoffs + (3*i+1)*Machine->uifontheight/2;
  817.         curr_dt++;
  818.     }
  819.     dt[curr_dt].text = lefthilight;
  820.     dt[curr_dt].color = UI_COLOR_NORMAL;
  821.     dt[curr_dt].x = leftoffs + Machine->uifontwidth/2;
  822.     dt[curr_dt].y = topoffs + (3*i+1)*Machine->uifontheight/2;
  823.     curr_dt++;
  824.  
  825.     dt[curr_dt].text = 0;    /* terminate array */
  826.  
  827.     displaytext(bitmap,dt,0,0);
  828.  
  829.     if (selected_long)
  830.     {
  831.         int long_dx;
  832.         int long_dy;
  833.         int long_x;
  834.         int long_y;
  835.         unsigned long_max;
  836.  
  837.         long_max = (Machine->uiwidth / Machine->uifontwidth) - 2;
  838.         multilinebox_size(&long_dx,&long_dy,subitems[selected],subitems[selected] + strlen(subitems[selected]), long_max);
  839.  
  840.         long_x = Machine->uiwidth - long_dx;
  841.         long_y = topoffs + (i+1) * 3*Machine->uifontheight/2;
  842.  
  843.         /* if too low display up */
  844.         if (long_y + long_dy > Machine->uiheight)
  845.             long_y = topoffs + i * 3*Machine->uifontheight/2 - long_dy;
  846.  
  847.         ui_multitextbox_ex(bitmap,subitems[selected],subitems[selected] + strlen(subitems[selected]), long_max, long_x,long_y,long_dx,long_dy, UI_COLOR_NORMAL);
  848.     }
  849. }
  850.  
  851.  
  852. void ui_displaymessagewindow(struct osd_bitmap *bitmap,const char *text)
  853. {
  854.     struct DisplayText dt[256];
  855.     int curr_dt;
  856.     char *c,*c2;
  857.     int i,len,maxlen,lines;
  858.     char textcopy[2048];
  859.     int leftoffs,topoffs;
  860.     int maxcols,maxrows;
  861.  
  862.     maxcols = (Machine->uiwidth / Machine->uifontwidth) - 1;
  863.     maxrows = (2 * Machine->uiheight - Machine->uifontheight) / (3 * Machine->uifontheight);
  864.  
  865.     /* copy text, calculate max len, count lines, wrap long lines and crop height to fit */
  866.     maxlen = 0;
  867.     lines = 0;
  868.     c = (char *)text;
  869.     c2 = textcopy;
  870.     while (*c)
  871.     {
  872.         len = 0;
  873.         while (*c && *c != '\n')
  874.         {
  875.             *c2++ = *c++;
  876.             len++;
  877.             if (len == maxcols && *c != '\n')
  878.             {
  879.                 /* attempt word wrap */
  880.                 char *csave = c, *c2save = c2;
  881.                 int lensave = len;
  882.  
  883.                 /* back up to last space or beginning of line */
  884.                 while (*c != ' ' && *c != '\n' && c > text)
  885.                     --c, --c2, --len;
  886.  
  887.                 /* if no space was found, hard wrap instead */
  888.                 if (*c != ' ')
  889.                     c = csave, c2 = c2save, len = lensave;
  890.                 else
  891.                     c++;
  892.  
  893.                 *c2++ = '\n'; /* insert wrap */
  894.                 break;
  895.             }
  896.         }
  897.  
  898.         if (*c == '\n')
  899.             *c2++ = *c++;
  900.  
  901.         if (len > maxlen) maxlen = len;
  902.  
  903.         lines++;
  904.         if (lines == maxrows)
  905.             break;
  906.     }
  907.     *c2 = '\0';
  908.  
  909.     maxlen += 1;
  910.  
  911.     leftoffs = (Machine->uiwidth - Machine->uifontwidth * maxlen) / 2;
  912.     if (leftoffs < 0) leftoffs = 0;
  913.     topoffs = (Machine->uiheight - (3 * lines + 1) * Machine->uifontheight / 2) / 2;
  914.  
  915.     /* black background */
  916.     ui_drawbox(bitmap,leftoffs,topoffs,maxlen * Machine->uifontwidth,(3 * lines + 1) * Machine->uifontheight / 2);
  917.  
  918.     curr_dt = 0;
  919.     c = textcopy;
  920.     i = 0;
  921.     while (*c)
  922.     {
  923.         c2 = c;
  924.         while (*c && *c != '\n')
  925.             c++;
  926.  
  927.         if (*c == '\n')
  928.         {
  929.             *c = '\0';
  930.             c++;
  931.         }
  932.  
  933.         if (*c2 == '\t')    /* center text */
  934.         {
  935.             c2++;
  936.             dt[curr_dt].x = (Machine->uiwidth - Machine->uifontwidth * (c - c2)) / 2;
  937.         }
  938.         else
  939.             dt[curr_dt].x = leftoffs + Machine->uifontwidth/2;
  940.  
  941.         dt[curr_dt].text = c2;
  942.         dt[curr_dt].color = UI_COLOR_NORMAL;
  943.         dt[curr_dt].y = topoffs + (3*i+1)*Machine->uifontheight/2;
  944.         curr_dt++;
  945.  
  946.         i++;
  947.     }
  948.  
  949.     dt[curr_dt].text = 0;    /* terminate array */
  950.  
  951.     displaytext(bitmap,dt,0,0);
  952. }
  953.  
  954.  
  955.  
  956. #ifndef NEOFREE
  957. #ifndef TINY_COMPILE
  958. extern int no_of_tiles;
  959. void NeoMVSDrawGfx(unsigned char **line,const struct GfxElement *gfx,
  960.         unsigned int code,unsigned int color,int flipx,int flipy,int sx,int sy,
  961.         int zx,int zy,const struct rectangle *clip);
  962. void NeoMVSDrawGfx16(unsigned char **line,const struct GfxElement *gfx,
  963.         unsigned int code,unsigned int color,int flipx,int flipy,int sx,int sy,
  964.         int zx,int zy,const struct rectangle *clip);
  965. extern struct GameDriver driver_neogeo;
  966. #endif
  967. #endif
  968.  
  969. static void showcharset(struct osd_bitmap *bitmap)
  970. {
  971.     int i;
  972.     char buf[80];
  973.     int bank,color,firstdrawn;
  974.     int palpage;
  975.     int changed;
  976.     int game_is_neogeo=0;
  977.     unsigned char *orig_used_colors=0;
  978.  
  979.  
  980.     if (palette_used_colors)
  981.     {
  982.         orig_used_colors = malloc(Machine->drv->total_colors * sizeof(unsigned char));
  983.         if (!orig_used_colors) return;
  984.  
  985.         memcpy(orig_used_colors,palette_used_colors,Machine->drv->total_colors * sizeof(unsigned char));
  986.     }
  987.  
  988. #ifndef NEOFREE
  989. #ifndef TINY_COMPILE
  990.     if (Machine->gamedrv->clone_of == &driver_neogeo ||
  991.             (Machine->gamedrv->clone_of &&
  992.                 Machine->gamedrv->clone_of->clone_of == &driver_neogeo))
  993.         game_is_neogeo=1;
  994. #endif
  995. #endif
  996.  
  997.     bank = -1;
  998.     color = 0;
  999.     firstdrawn = 0;
  1000.     palpage = 0;
  1001.  
  1002.     changed = 1;
  1003.  
  1004.     do
  1005.     {
  1006.         int cpx,cpy,skip_chars;
  1007.  
  1008.         if (bank >= 0)
  1009.         {
  1010.             cpx = Machine->uiwidth / Machine->gfx[bank]->width;
  1011.             cpy = (Machine->uiheight - Machine->uifontheight) / Machine->gfx[bank]->height;
  1012.             skip_chars = cpx * cpy;
  1013.         }
  1014.         else cpx = cpy = skip_chars = 0;
  1015.  
  1016.         if (changed)
  1017.         {
  1018.             int lastdrawn=0;
  1019.  
  1020.             osd_clearbitmap(bitmap);
  1021.  
  1022.             /* validity chack after char bank change */
  1023.             if (bank >= 0)
  1024.             {
  1025.                 if (firstdrawn >= Machine->gfx[bank]->total_elements)
  1026.                 {
  1027.                     firstdrawn = Machine->gfx[bank]->total_elements - skip_chars;
  1028.                     if (firstdrawn < 0) firstdrawn = 0;
  1029.                 }
  1030.             }
  1031.  
  1032.             if(bank!=2 || !game_is_neogeo)
  1033.             {
  1034.                 switch_ui_orientation();
  1035.  
  1036.                 if (bank >= 0)
  1037.                 {
  1038.                     int table_offs;
  1039.                     int flipx,flipy;
  1040.  
  1041.                     if (palette_used_colors)
  1042.                     {
  1043.                         memset(palette_used_colors,PALETTE_COLOR_TRANSPARENT,Machine->drv->total_colors * sizeof(unsigned char));
  1044.                         table_offs = Machine->gfx[bank]->colortable - Machine->remapped_colortable
  1045.                                 + Machine->gfx[bank]->color_granularity * color;
  1046.                         for (i = 0;i < Machine->gfx[bank]->color_granularity;i++)
  1047.                             palette_used_colors[Machine->game_colortable[table_offs + i]] = PALETTE_COLOR_USED;
  1048.                         palette_recalc();    /* do it twice in case of previous overflow */
  1049.                         palette_recalc();    /*(we redraw the screen only when it changes) */
  1050.                     }
  1051.  
  1052. #ifndef PREROTATE_GFX
  1053.                     flipx = (Machine->orientation ^ trueorientation) & ORIENTATION_FLIP_X;
  1054.                     flipy = (Machine->orientation ^ trueorientation) & ORIENTATION_FLIP_Y;
  1055.  
  1056.                     if (Machine->orientation & ORIENTATION_SWAP_XY)
  1057.                     {
  1058.                         int t;
  1059.                         t = flipx; flipx = flipy; flipy = t;
  1060.                     }
  1061. #else
  1062.                     flipx = 0;
  1063.                     flipy = 0;
  1064. #endif
  1065.  
  1066.                     for (i = 0; i+firstdrawn < Machine->gfx[bank]->total_elements && i<cpx*cpy; i++)
  1067.                     {
  1068.                         drawgfx(bitmap,Machine->gfx[bank],
  1069.                                 i+firstdrawn,color,  /*sprite num, color*/
  1070.                                 flipx,flipy,
  1071.                                 (i % cpx) * Machine->gfx[bank]->width + Machine->uixmin,
  1072.                                 Machine->uifontheight + (i / cpx) * Machine->gfx[bank]->height + Machine->uiymin,
  1073.                                 0,TRANSPARENCY_NONE,0);
  1074.  
  1075.                         lastdrawn = i+firstdrawn;
  1076.                     }
  1077.                 }
  1078.                 else
  1079.                 {
  1080.                     int sx,sy,x,y,colors;
  1081.  
  1082.                     colors = Machine->drv->total_colors - 256 * palpage;
  1083.                     if (colors > 256) colors = 256;
  1084.                     if (palette_used_colors)
  1085.                     {
  1086.                         memset(palette_used_colors,PALETTE_COLOR_UNUSED,Machine->drv->total_colors * sizeof(unsigned char));
  1087.                         memset(palette_used_colors+256*palpage,PALETTE_COLOR_USED,colors * sizeof(unsigned char));
  1088.                         palette_recalc();    /* do it twice in case of previous overflow */
  1089.                         palette_recalc();    /*(we redraw the screen only when it changes) */
  1090.                     }
  1091.  
  1092.                     for (i = 0;i < 16;i++)
  1093.                     {
  1094.                         char bf[40];
  1095.  
  1096.                         sx = 3*Machine->uifontwidth + (Machine->uifontwidth*4/3)*(i % 16);
  1097.                         sprintf(bf,"%X",i);
  1098.                         ui_text(bitmap,bf,sx,2*Machine->uifontheight);
  1099.                         if (16*i < colors)
  1100.                         {
  1101.                             sy = 3*Machine->uifontheight + (Machine->uifontheight)*(i % 16);
  1102.                             sprintf(bf,"%3X",i+16*palpage);
  1103.                             ui_text(bitmap,bf,0,sy);
  1104.                         }
  1105.                     }
  1106.  
  1107.                     for (i = 0;i < colors;i++)
  1108.                     {
  1109.                         sx = Machine->uixmin + 3*Machine->uifontwidth + (Machine->uifontwidth*4/3)*(i % 16);
  1110.                         sy = Machine->uiymin + 2*Machine->uifontheight + (Machine->uifontheight)*(i / 16) + Machine->uifontheight;
  1111.                         for (y = 0;y < Machine->uifontheight;y++)
  1112.                         {
  1113.                             for (x = 0;x < Machine->uifontwidth*4/3;x++)
  1114.                             {
  1115.                                 plot_pixel(bitmap, sx+x, sy+y, Machine->pens[i + 256*palpage]);
  1116.                             }
  1117.                         }
  1118.                     }
  1119.                 }
  1120.  
  1121.                 switch_true_orientation();
  1122.             }
  1123. #ifndef NEOFREE
  1124. #ifndef TINY_COMPILE
  1125.             else    /* neogeo sprite tiles */
  1126.             {
  1127.                 struct rectangle clip;
  1128.  
  1129.                 clip.min_x = Machine->uixmin;
  1130.                 clip.max_x = Machine->uixmin + Machine->uiwidth - 1;
  1131.                 clip.min_y = Machine->uiymin;
  1132.                 clip.max_y = Machine->uiymin + Machine->uiheight - 1;
  1133.  
  1134.                 if (palette_used_colors)
  1135.                 {
  1136.                     memset(palette_used_colors,PALETTE_COLOR_TRANSPARENT,Machine->drv->total_colors * sizeof(unsigned char));
  1137.                     memset(palette_used_colors+Machine->gfx[bank]->color_granularity*color,PALETTE_COLOR_USED,Machine->gfx[bank]->color_granularity * sizeof(unsigned char));
  1138.                     palette_recalc();    /* do it twice in case of previous overflow */
  1139.                     palette_recalc();    /*(we redraw the screen only when it changes) */
  1140.                 }
  1141.  
  1142.                 for (i = 0; i+firstdrawn < no_of_tiles && i<cpx*cpy; i++)
  1143.                 {
  1144.                     if (bitmap->depth == 16)
  1145.                         NeoMVSDrawGfx16(bitmap->line,Machine->gfx[bank],
  1146.                             i+firstdrawn,color,  /*sprite num, color*/
  1147.                             0,0,
  1148.                             (i % cpx) * Machine->gfx[bank]->width + Machine->uixmin,
  1149.                             Machine->uifontheight+1 + (i / cpx) * Machine->gfx[bank]->height + Machine->uiymin,
  1150.                             16,16,&clip);
  1151.                     else
  1152.                         NeoMVSDrawGfx(bitmap->line,Machine->gfx[bank],
  1153.                             i+firstdrawn,color,  /*sprite num, color*/
  1154.                             0,0,
  1155.                             (i % cpx) * Machine->gfx[bank]->width + Machine->uixmin,
  1156.                             Machine->uifontheight+1 + (i / cpx) * Machine->gfx[bank]->height + Machine->uiymin,
  1157.                             16,16,&clip);
  1158.  
  1159.                     lastdrawn = i+firstdrawn;
  1160.                 }
  1161.             }
  1162. #endif
  1163. #endif
  1164.  
  1165.             if (bank >= 0)
  1166.                 sprintf(buf,"GFXSET %d COLOR %2X CODE %X-%X",bank,color,firstdrawn,lastdrawn);
  1167.             else
  1168.                 strcpy(buf,"PALETTE");
  1169.             ui_text(bitmap,buf,0,0);
  1170.  
  1171.             changed = 0;
  1172.         }
  1173.  
  1174.         /* the OS dependant code must not assume that */
  1175.         /* osd_skip_this_frame() is called before osd_update_video_and_audio() - NS */
  1176.         update_video_and_audio();
  1177.  
  1178.         if (code_pressed(KEYCODE_LCONTROL) || code_pressed(KEYCODE_RCONTROL))
  1179.         {
  1180.             skip_chars = cpx;
  1181.         }
  1182.         if (code_pressed(KEYCODE_LSHIFT) || code_pressed(KEYCODE_RSHIFT))
  1183.         {
  1184.             skip_chars = 1;
  1185.         }
  1186.  
  1187.  
  1188.         if (input_ui_pressed_repeat(IPT_UI_RIGHT,8))
  1189.         {
  1190.             if (bank+1 < MAX_GFX_ELEMENTS && Machine->gfx[bank + 1])
  1191.             {
  1192.                 bank++;
  1193. //                firstdrawn = 0;
  1194.                 changed = 1;
  1195.             }
  1196.         }
  1197.  
  1198.         if (input_ui_pressed_repeat(IPT_UI_LEFT,8))
  1199.         {
  1200.             if (bank > -1)
  1201.             {
  1202.                 bank--;
  1203. //                firstdrawn = 0;
  1204.                 changed = 1;
  1205.             }
  1206.         }
  1207.  
  1208.         if (code_pressed_memory_repeat(KEYCODE_PGDN,4))
  1209.         {
  1210.             if (bank >= 0)
  1211.             {
  1212.                 if (firstdrawn + skip_chars < Machine->gfx[bank]->total_elements)
  1213.                 {
  1214.                     firstdrawn += skip_chars;
  1215.                     changed = 1;
  1216.                 }
  1217.             }
  1218.             else
  1219.             {
  1220.                 if (256 * (palpage + 1) < Machine->drv->total_colors)
  1221.                 {
  1222.                     palpage++;
  1223.                     changed = 1;
  1224.                 }
  1225.             }
  1226.         }
  1227.  
  1228.         if (code_pressed_memory_repeat(KEYCODE_PGUP,4))
  1229.         {
  1230.             if (bank >= 0)
  1231.             {
  1232.                 firstdrawn -= skip_chars;
  1233.                 if (firstdrawn < 0) firstdrawn = 0;
  1234.                 changed = 1;
  1235.             }
  1236.             else
  1237.             {
  1238.                 if (palpage > 0)
  1239.                 {
  1240.                     palpage--;
  1241.                     changed = 1;
  1242.                 }
  1243.             }
  1244.         }
  1245.  
  1246.         if (input_ui_pressed_repeat(IPT_UI_UP,6))
  1247.         {
  1248.             if (bank >= 0)
  1249.             {
  1250.                 if (color < Machine->gfx[bank]->total_colors - 1)
  1251.                 {
  1252.                     color++;
  1253.                     changed = 1;
  1254.                 }
  1255.             }
  1256.         }
  1257.  
  1258.         if (input_ui_pressed_repeat(IPT_UI_DOWN,6))
  1259.         {
  1260.             if (color > 0)
  1261.             {
  1262.                 color--;
  1263.                 changed = 1;
  1264.             }
  1265.         }
  1266.  
  1267.         if (input_ui_pressed(IPT_UI_SNAPSHOT))
  1268.             osd_save_snapshot();
  1269.     } while (!input_ui_pressed(IPT_UI_SHOW_GFX) &&
  1270.             !input_ui_pressed(IPT_UI_CANCEL));
  1271.  
  1272.     /* clear the screen before returning */
  1273.     osd_clearbitmap(bitmap);
  1274.  
  1275.     if (palette_used_colors)
  1276.     {
  1277.         /* this should force a full refresh by the video driver */
  1278.         memset(palette_used_colors,PALETTE_COLOR_TRANSPARENT,Machine->drv->total_colors * sizeof(unsigned char));
  1279.         palette_recalc();
  1280.         /* restore the game used colors array */
  1281.         memcpy(palette_used_colors,orig_used_colors,Machine->drv->total_colors * sizeof(unsigned char));
  1282.         free(orig_used_colors);
  1283.     }
  1284.  
  1285.     return;
  1286. }
  1287.  
  1288.  
  1289. #ifdef MAME_DEBUG
  1290. static void showtotalcolors(struct osd_bitmap *bitmap)
  1291. {
  1292.     char *used;
  1293.     int i,l,x,y,total;
  1294.     unsigned char r,g,b;
  1295.     char buf[40];
  1296.  
  1297.  
  1298.     used = malloc(64*64*64);
  1299.     if (!used) return;
  1300.  
  1301.     for (i = 0;i < 64*64*64;i++)
  1302.         used[i] = 0;
  1303.  
  1304.     for (y = 0;y < bitmap->height;y++)
  1305.     {
  1306.         for (x = 0;x < bitmap->width;x++)
  1307.         {
  1308.             osd_get_pen(read_pixel(bitmap,x,y),&r,&g,&b);
  1309.             r >>= 2;
  1310.             g >>= 2;
  1311.             b >>= 2;
  1312.             used[64*64*r+64*g+b] = 1;
  1313.         }
  1314.     }
  1315.  
  1316.     total = 0;
  1317.     for (i = 0;i < 64*64*64;i++)
  1318.         if (used[i]) total++;
  1319.  
  1320.     switch_ui_orientation();
  1321.  
  1322.     sprintf(buf,"%5d colors",total);
  1323.     l = strlen(buf);
  1324.     for (i = 0;i < l;i++)
  1325.         drawgfx(bitmap,Machine->uifont,buf[i],total>256?UI_COLOR_INVERSE:UI_COLOR_NORMAL,0,0,Machine->uixmin+i*Machine->uifontwidth,Machine->uiymin,0,TRANSPARENCY_NONE,0);
  1326.  
  1327.     switch_true_orientation();
  1328.  
  1329.     free(used);
  1330. }
  1331. #endif
  1332.  
  1333.  
  1334. static int setdipswitches(struct osd_bitmap *bitmap,int selected)
  1335. {
  1336.     const char *menu_item[128];
  1337.     const char *menu_subitem[128];
  1338.     struct InputPort *entry[128];
  1339.     char flag[40];
  1340.     int i,sel;
  1341.     struct InputPort *in;
  1342.     int total;
  1343.     int arrowize;
  1344.  
  1345.  
  1346.     sel = selected - 1;
  1347.  
  1348.  
  1349.     in = Machine->input_ports;
  1350.  
  1351.     total = 0;
  1352.     while (in->type != IPT_END)
  1353.     {
  1354.         if ((in->type & ~IPF_MASK) == IPT_DIPSWITCH_NAME && input_port_name(in) != 0 &&
  1355.                 (in->type & IPF_UNUSED) == 0 &&
  1356.                 !(!options.cheat && (in->type & IPF_CHEAT)))
  1357.         {
  1358.             entry[total] = in;
  1359.             menu_item[total] = input_port_name(in);
  1360.  
  1361.             total++;
  1362.         }
  1363.  
  1364.         in++;
  1365.     }
  1366.  
  1367.     if (total == 0) return 0;
  1368.  
  1369.     menu_item[total] = ui_getstring (UI_returntomain);
  1370.     menu_item[total + 1] = 0;    /* terminate array */
  1371.     total++;
  1372.  
  1373.  
  1374.     for (i = 0;i < total;i++)
  1375.     {
  1376.         flag[i] = 0; /* TODO: flag the dip if it's not the real default */
  1377.         if (i < total - 1)
  1378.         {
  1379.             in = entry[i] + 1;
  1380.             while ((in->type & ~IPF_MASK) == IPT_DIPSWITCH_SETTING &&
  1381.                     in->default_value != entry[i]->default_value)
  1382.                 in++;
  1383.  
  1384.             if ((in->type & ~IPF_MASK) != IPT_DIPSWITCH_SETTING)
  1385.                 menu_subitem[i] = ui_getstring (UI_INVALID);
  1386.             else menu_subitem[i] = input_port_name(in);
  1387.         }
  1388.         else menu_subitem[i] = 0;    /* no subitem */
  1389.     }
  1390.  
  1391.     arrowize = 0;
  1392.     if (sel < total - 1)
  1393.     {
  1394.         in = entry[sel] + 1;
  1395.         while ((in->type & ~IPF_MASK) == IPT_DIPSWITCH_SETTING &&
  1396.                 in->default_value != entry[sel]->default_value)
  1397.             in++;
  1398.  
  1399.         if ((in->type & ~IPF_MASK) != IPT_DIPSWITCH_SETTING)
  1400.             /* invalid setting: revert to a valid one */
  1401.             arrowize |= 1;
  1402.         else
  1403.         {
  1404.             if (((in-1)->type & ~IPF_MASK) == IPT_DIPSWITCH_SETTING &&
  1405.                     !(!options.cheat && ((in-1)->type & IPF_CHEAT)))
  1406.                 arrowize |= 1;
  1407.         }
  1408.     }
  1409.     if (sel < total - 1)
  1410.     {
  1411.         in = entry[sel] + 1;
  1412.         while ((in->type & ~IPF_MASK) == IPT_DIPSWITCH_SETTING &&
  1413.                 in->default_value != entry[sel]->default_value)
  1414.             in++;
  1415.  
  1416.         if ((in->type & ~IPF_MASK) != IPT_DIPSWITCH_SETTING)
  1417.             /* invalid setting: revert to a valid one */
  1418.             arrowize |= 2;
  1419.         else
  1420.         {
  1421.             if (((in+1)->type & ~IPF_MASK) == IPT_DIPSWITCH_SETTING &&
  1422.                     !(!options.cheat && ((in+1)->type & IPF_CHEAT)))
  1423.                 arrowize |= 2;
  1424.         }
  1425.     }
  1426.  
  1427.     ui_displaymenu(bitmap,menu_item,menu_subitem,flag,sel,arrowize);
  1428.  
  1429.     if (input_ui_pressed_repeat(IPT_UI_DOWN,8))
  1430.         sel = (sel + 1) % total;
  1431.  
  1432.     if (input_ui_pressed_repeat(IPT_UI_UP,8))
  1433.         sel = (sel + total - 1) % total;
  1434.  
  1435.     if (input_ui_pressed_repeat(IPT_UI_RIGHT,8))
  1436.     {
  1437.         if (sel < total - 1)
  1438.         {
  1439.             in = entry[sel] + 1;
  1440.             while ((in->type & ~IPF_MASK) == IPT_DIPSWITCH_SETTING &&
  1441.                     in->default_value != entry[sel]->default_value)
  1442.                 in++;
  1443.  
  1444.             if ((in->type & ~IPF_MASK) != IPT_DIPSWITCH_SETTING)
  1445.                 /* invalid setting: revert to a valid one */
  1446.                 entry[sel]->default_value = (entry[sel]+1)->default_value & entry[sel]->mask;
  1447.             else
  1448.             {
  1449.                 if (((in+1)->type & ~IPF_MASK) == IPT_DIPSWITCH_SETTING &&
  1450.                         !(!options.cheat && ((in+1)->type & IPF_CHEAT)))
  1451.                     entry[sel]->default_value = (in+1)->default_value & entry[sel]->mask;
  1452.             }
  1453.  
  1454.             /* tell updatescreen() to clean after us (in case the window changes size) */
  1455.             need_to_clear_bitmap = 1;
  1456.         }
  1457.     }
  1458.  
  1459.     if (input_ui_pressed_repeat(IPT_UI_LEFT,8))
  1460.     {
  1461.         if (sel < total - 1)
  1462.         {
  1463.             in = entry[sel] + 1;
  1464.             while ((in->type & ~IPF_MASK) == IPT_DIPSWITCH_SETTING &&
  1465.                     in->default_value != entry[sel]->default_value)
  1466.                 in++;
  1467.  
  1468.             if ((in->type & ~IPF_MASK) != IPT_DIPSWITCH_SETTING)
  1469.                 /* invalid setting: revert to a valid one */
  1470.                 entry[sel]->default_value = (entry[sel]+1)->default_value & entry[sel]->mask;
  1471.             else
  1472.             {
  1473.                 if (((in-1)->type & ~IPF_MASK) == IPT_DIPSWITCH_SETTING &&
  1474.                         !(!options.cheat && ((in-1)->type & IPF_CHEAT)))
  1475.                     entry[sel]->default_value = (in-1)->default_value & entry[sel]->mask;
  1476.             }
  1477.  
  1478.             /* tell updatescreen() to clean after us (in case the window changes size) */
  1479.             need_to_clear_bitmap = 1;
  1480.         }
  1481.     }
  1482.  
  1483.     if (input_ui_pressed(IPT_UI_SELECT))
  1484.     {
  1485.         if (sel == total - 1) sel = -1;
  1486.     }
  1487.  
  1488.     if (input_ui_pressed(IPT_UI_CANCEL))
  1489.         sel = -1;
  1490.  
  1491.     if (input_ui_pressed(IPT_UI_CONFIGURE))
  1492.         sel = -2;
  1493.  
  1494.     if (sel == -1 || sel == -2)
  1495.     {
  1496.         /* tell updatescreen() to clean after us */
  1497.         need_to_clear_bitmap = 1;
  1498.     }
  1499.  
  1500.     return sel + 1;
  1501. }
  1502.  
  1503. /* This flag is used for record OR sequence of key/joy */
  1504. /* when is !=0 the first sequence is record, otherwise the first free */
  1505. /* it's used byt setdefkeysettings, setdefjoysettings, setkeysettings, setjoysettings */
  1506. static int record_first_insert = 1;
  1507.  
  1508. static char menu_subitem_buffer[400][96];
  1509.  
  1510. static int setdefcodesettings(struct osd_bitmap *bitmap,int selected)
  1511. {
  1512.     const char *menu_item[400];
  1513.     const char *menu_subitem[400];
  1514.     struct ipd *entry[400];
  1515.     char flag[400];
  1516.     int i,sel;
  1517.     struct ipd *in;
  1518.     int total;
  1519.     extern struct ipd inputport_defaults[];
  1520.  
  1521.     sel = selected - 1;
  1522.  
  1523.  
  1524.     if (Machine->input_ports == 0)
  1525.         return 0;
  1526.  
  1527.     in = inputport_defaults;
  1528.  
  1529.     total = 0;
  1530.     while (in->type != IPT_END)
  1531.     {
  1532.         if (in->name != 0  && (in->type & ~IPF_MASK) != IPT_UNKNOWN && (in->type & IPF_UNUSED) == 0
  1533.             && !(!options.cheat && (in->type & IPF_CHEAT)))
  1534.         {
  1535.             entry[total] = in;
  1536.             menu_item[total] = in->name;
  1537.  
  1538.             total++;
  1539.         }
  1540.  
  1541.         in++;
  1542.     }
  1543.  
  1544.     if (total == 0) return 0;
  1545.  
  1546.     menu_item[total] = ui_getstring (UI_returntomain);
  1547.     menu_item[total + 1] = 0;    /* terminate array */
  1548.     total++;
  1549.  
  1550.     for (i = 0;i < total;i++)
  1551.     {
  1552.         if (i < total - 1)
  1553.         {
  1554.             seq_name(&entry[i]->seq,menu_subitem_buffer[i],sizeof(menu_subitem_buffer[0]));
  1555.             menu_subitem[i] = menu_subitem_buffer[i];
  1556.         } else
  1557.             menu_subitem[i] = 0;    /* no subitem */
  1558.         flag[i] = 0;
  1559.     }
  1560.  
  1561.     if (sel > SEL_MASK)   /* are we waiting for a new key? */
  1562.     {
  1563.         int ret;
  1564.  
  1565.         menu_subitem[sel & SEL_MASK] = "    ";
  1566.         ui_displaymenu(bitmap,menu_item,menu_subitem,flag,sel & SEL_MASK,3);
  1567.  
  1568.         ret = seq_read_async(&entry[sel & SEL_MASK]->seq,record_first_insert);
  1569.  
  1570.         if (ret >= 0)
  1571.         {
  1572.             sel &= 0xff;
  1573.  
  1574.             if (ret > 0 || seq_get_1(&entry[sel]->seq) == CODE_NONE)
  1575.             {
  1576.                 seq_set_1(&entry[sel]->seq,CODE_NONE);
  1577.                 ret = 1;
  1578.             }
  1579.  
  1580.             /* tell updatescreen() to clean after us (in case the window changes size) */
  1581.             need_to_clear_bitmap = 1;
  1582.  
  1583.             record_first_insert = ret != 0;
  1584.         }
  1585.  
  1586.  
  1587.         return sel + 1;
  1588.     }
  1589.  
  1590.  
  1591.     ui_displaymenu(bitmap,menu_item,menu_subitem,flag,sel,0);
  1592.  
  1593.     if (input_ui_pressed_repeat(IPT_UI_DOWN,8))
  1594.     {
  1595.         sel = (sel + 1) % total;
  1596.         record_first_insert = 1;
  1597.     }
  1598.  
  1599.     if (input_ui_pressed_repeat(IPT_UI_UP,8))
  1600.     {
  1601.         sel = (sel + total - 1) % total;
  1602.         record_first_insert = 1;
  1603.     }
  1604.  
  1605.     if (input_ui_pressed(IPT_UI_SELECT))
  1606.     {
  1607.         if (sel == total - 1) sel = -1;
  1608.         else
  1609.         {
  1610.             seq_read_async_start();
  1611.  
  1612.             sel |= 1 << SEL_BITS;    /* we'll ask for a key */
  1613.  
  1614.             /* tell updatescreen() to clean after us (in case the window changes size) */
  1615.             need_to_clear_bitmap = 1;
  1616.         }
  1617.     }
  1618.  
  1619.     if (input_ui_pressed(IPT_UI_CANCEL))
  1620.         sel = -1;
  1621.  
  1622.     if (input_ui_pressed(IPT_UI_CONFIGURE))
  1623.         sel = -2;
  1624.  
  1625.     if (sel == -1 || sel == -2)
  1626.     {
  1627.         /* tell updatescreen() to clean after us */
  1628.         need_to_clear_bitmap = 1;
  1629.  
  1630.         record_first_insert = 1;
  1631.     }
  1632.  
  1633.     return sel + 1;
  1634. }
  1635.  
  1636.  
  1637.  
  1638. static int setcodesettings(struct osd_bitmap *bitmap,int selected)
  1639. {
  1640.     const char *menu_item[400];
  1641.     const char *menu_subitem[400];
  1642.     struct InputPort *entry[400];
  1643.     char flag[400];
  1644.     int i,sel;
  1645.     struct InputPort *in;
  1646.     int total;
  1647.  
  1648.  
  1649.     sel = selected - 1;
  1650.  
  1651.  
  1652.     if (Machine->input_ports == 0)
  1653.         return 0;
  1654.  
  1655.     in = Machine->input_ports;
  1656.  
  1657.     total = 0;
  1658.     while (in->type != IPT_END)
  1659.     {
  1660.         if (input_port_name(in) != 0 && seq_get_1(&in->seq) != CODE_NONE && (in->type & ~IPF_MASK) != IPT_UNKNOWN)
  1661.         {
  1662.             entry[total] = in;
  1663.             menu_item[total] = input_port_name(in);
  1664.  
  1665.             total++;
  1666.         }
  1667.  
  1668.         in++;
  1669.     }
  1670.  
  1671.     if (total == 0) return 0;
  1672.  
  1673.     menu_item[total] = ui_getstring (UI_returntomain);
  1674.     menu_item[total + 1] = 0;    /* terminate array */
  1675.     total++;
  1676.  
  1677.     for (i = 0;i < total;i++)
  1678.     {
  1679.         if (i < total - 1)
  1680.         {
  1681.             seq_name(input_port_seq(entry[i]),menu_subitem_buffer[i],sizeof(menu_subitem_buffer[0]));
  1682.             menu_subitem[i] = menu_subitem_buffer[i];
  1683.  
  1684.             /* If the key isn't the default, flag it */
  1685.             if (seq_get_1(&entry[i]->seq) != CODE_DEFAULT)
  1686.                 flag[i] = 1;
  1687.             else
  1688.                 flag[i] = 0;
  1689.  
  1690.         } else
  1691.             menu_subitem[i] = 0;    /* no subitem */
  1692.     }
  1693.  
  1694.     if (sel > SEL_MASK)   /* are we waiting for a new key? */
  1695.     {
  1696.         int ret;
  1697.  
  1698.         menu_subitem[sel & SEL_MASK] = "    ";
  1699.         ui_displaymenu(bitmap,menu_item,menu_subitem,flag,sel & SEL_MASK,3);
  1700.  
  1701.         ret = seq_read_async(&entry[sel & SEL_MASK]->seq,record_first_insert);
  1702.  
  1703.         if (ret >= 0)
  1704.         {
  1705.             sel &= 0xff;
  1706.  
  1707.             if (ret > 0 || seq_get_1(&entry[sel]->seq) == CODE_NONE)
  1708.             {
  1709.                 seq_set_1(&entry[sel]->seq, CODE_DEFAULT);
  1710.                 ret = 1;
  1711.             }
  1712.  
  1713.             /* tell updatescreen() to clean after us (in case the window changes size) */
  1714.             need_to_clear_bitmap = 1;
  1715.  
  1716.             record_first_insert = ret != 0;
  1717.         }
  1718.  
  1719.         return sel + 1;
  1720.     }
  1721.  
  1722.  
  1723.     ui_displaymenu(bitmap,menu_item,menu_subitem,flag,sel,0);
  1724.  
  1725.     if (input_ui_pressed_repeat(IPT_UI_DOWN,8))
  1726.     {
  1727.         sel = (sel + 1) % total;
  1728.         record_first_insert = 1;
  1729.     }
  1730.  
  1731.     if (input_ui_pressed_repeat(IPT_UI_UP,8))
  1732.     {
  1733.         sel = (sel + total - 1) % total;
  1734.         record_first_insert = 1;
  1735.     }
  1736.  
  1737.     if (input_ui_pressed(IPT_UI_SELECT))
  1738.     {
  1739.         if (sel == total - 1) sel = -1;
  1740.         else
  1741.         {
  1742.             seq_read_async_start();
  1743.  
  1744.             sel |= 1 << SEL_BITS;    /* we'll ask for a key */
  1745.  
  1746.             /* tell updatescreen() to clean after us (in case the window changes size) */
  1747.             need_to_clear_bitmap = 1;
  1748.         }
  1749.     }
  1750.  
  1751.     if (input_ui_pressed(IPT_UI_CANCEL))
  1752.         sel = -1;
  1753.  
  1754.     if (input_ui_pressed(IPT_UI_CONFIGURE))
  1755.         sel = -2;
  1756.  
  1757.     if (sel == -1 || sel == -2)
  1758.     {
  1759.         /* tell updatescreen() to clean after us */
  1760.         need_to_clear_bitmap = 1;
  1761.  
  1762.         record_first_insert = 1;
  1763.     }
  1764.  
  1765.     return sel + 1;
  1766. }
  1767.  
  1768.  
  1769. static int calibratejoysticks(struct osd_bitmap *bitmap,int selected)
  1770. {
  1771.     char *msg;
  1772.     char buf[2048];
  1773.     int sel;
  1774.     static int calibration_started = 0;
  1775.  
  1776.     sel = selected - 1;
  1777.  
  1778.     if (calibration_started == 0)
  1779.     {
  1780.         osd_joystick_start_calibration();
  1781.         calibration_started = 1;
  1782.         strcpy (buf, "");
  1783.     }
  1784.  
  1785.     if (sel > SEL_MASK) /* Waiting for the user to acknowledge joystick movement */
  1786.     {
  1787.         if (input_ui_pressed(IPT_UI_CANCEL))
  1788.         {
  1789.             calibration_started = 0;
  1790.             sel = -1;
  1791.         }
  1792.         else if (input_ui_pressed(IPT_UI_SELECT))
  1793.         {
  1794.             osd_joystick_calibrate();
  1795.             sel &= 0xff;
  1796.         }
  1797.  
  1798.         ui_displaymessagewindow(bitmap,buf);
  1799.     }
  1800.     else
  1801.     {
  1802.         msg = osd_joystick_calibrate_next();
  1803.         need_to_clear_bitmap = 1;
  1804.         if (msg == 0)
  1805.         {
  1806.             calibration_started = 0;
  1807.             osd_joystick_end_calibration();
  1808.             sel = -1;
  1809.         }
  1810.         else
  1811.         {
  1812.             strcpy (buf, msg);
  1813.             ui_displaymessagewindow(bitmap,buf);
  1814.             sel |= 1 << SEL_BITS;
  1815.         }
  1816.     }
  1817.  
  1818.     if (input_ui_pressed(IPT_UI_CONFIGURE))
  1819.         sel = -2;
  1820.  
  1821.     if (sel == -1 || sel == -2)
  1822.     {
  1823.         /* tell updatescreen() to clean after us */
  1824.         need_to_clear_bitmap = 1;
  1825.     }
  1826.  
  1827.     return sel + 1;
  1828. }
  1829.  
  1830.  
  1831. static int settraksettings(struct osd_bitmap *bitmap,int selected)
  1832. {
  1833.     const char *menu_item[40];
  1834.     const char *menu_subitem[40];
  1835.     struct InputPort *entry[40];
  1836.     int i,sel;
  1837.     struct InputPort *in;
  1838.     int total,total2;
  1839.     int arrowize;
  1840.  
  1841.  
  1842.     sel = selected - 1;
  1843.  
  1844.  
  1845.     if (Machine->input_ports == 0)
  1846.         return 0;
  1847.  
  1848.     in = Machine->input_ports;
  1849.  
  1850.     /* Count the total number of analog controls */
  1851.     total = 0;
  1852.     while (in->type != IPT_END)
  1853.     {
  1854.         if (((in->type & 0xff) > IPT_ANALOG_START) && ((in->type & 0xff) < IPT_ANALOG_END)
  1855.                 && !(!options.cheat && (in->type & IPF_CHEAT)))
  1856.         {
  1857.             entry[total] = in;
  1858.             total++;
  1859.         }
  1860.         in++;
  1861.     }
  1862.  
  1863.     if (total == 0) return 0;
  1864.  
  1865.     /* Each analog control has 3 entries - key & joy delta, reverse, sensitivity */
  1866.  
  1867. #define ENTRIES 3
  1868.  
  1869.     total2 = total * ENTRIES;
  1870.  
  1871.     menu_item[total2] = ui_getstring (UI_returntomain);
  1872.     menu_item[total2 + 1] = 0;    /* terminate array */
  1873.     total2++;
  1874.  
  1875.     arrowize = 0;
  1876.     for (i = 0;i < total2;i++)
  1877.     {
  1878.         if (i < total2 - 1)
  1879.         {
  1880.             char label[30][40];
  1881.             char setting[30][40];
  1882.             int sensitivity,delta;
  1883.             int reverse;
  1884.  
  1885.             strcpy (label[i], input_port_name(entry[i/ENTRIES]));
  1886.             sensitivity = IP_GET_SENSITIVITY(entry[i/ENTRIES]);
  1887.             delta = IP_GET_DELTA(entry[i/ENTRIES]);
  1888.             reverse = (entry[i/ENTRIES]->type & IPF_REVERSE);
  1889.  
  1890.             strcat (label[i], " ");
  1891.             switch (i%ENTRIES)
  1892.             {
  1893.                 case 0:
  1894.                     strcat (label[i], ui_getstring (UI_keyjoyspeed));
  1895.                     sprintf(setting[i],"%d",delta);
  1896.                     if (i == sel) arrowize = 3;
  1897.                     break;
  1898.                 case 1:
  1899.                     strcat (label[i], ui_getstring (UI_reverse));
  1900.                     if (reverse)
  1901.                         sprintf(setting[i],ui_getstring (UI_on));
  1902.                     else
  1903.                         sprintf(setting[i],ui_getstring (UI_off));
  1904.                     if (i == sel) arrowize = 3;
  1905.                     break;
  1906.                 case 2:
  1907.                     strcat (label[i], ui_getstring (UI_sensitivity));
  1908.                     sprintf(setting[i],"%3d%%",sensitivity);
  1909.                     if (i == sel) arrowize = 3;
  1910.                     break;
  1911.             }
  1912.  
  1913.             menu_item[i] = label[i];
  1914.             menu_subitem[i] = setting[i];
  1915.  
  1916.             in++;
  1917.         }
  1918.         else menu_subitem[i] = 0;    /* no subitem */
  1919.     }
  1920.  
  1921.     ui_displaymenu(bitmap,menu_item,menu_subitem,0,sel,arrowize);
  1922.  
  1923.     if (input_ui_pressed_repeat(IPT_UI_DOWN,8))
  1924.         sel = (sel + 1) % total2;
  1925.  
  1926.     if (input_ui_pressed_repeat(IPT_UI_UP,8))
  1927.         sel = (sel + total2 - 1) % total2;
  1928.  
  1929.     if (input_ui_pressed_repeat(IPT_UI_LEFT,8))
  1930.     {
  1931.         if ((sel % ENTRIES) == 0)
  1932.         /* keyboard/joystick delta */
  1933.         {
  1934.             int val = IP_GET_DELTA(entry[sel/ENTRIES]);
  1935.  
  1936.             val --;
  1937.             if (val < 1) val = 1;
  1938.             IP_SET_DELTA(entry[sel/ENTRIES],val);
  1939.         }
  1940.         else if ((sel % ENTRIES) == 1)
  1941.         /* reverse */
  1942.         {
  1943.             int reverse = entry[sel/ENTRIES]->type & IPF_REVERSE;
  1944.             if (reverse)
  1945.                 reverse=0;
  1946.             else
  1947.                 reverse=IPF_REVERSE;
  1948.             entry[sel/ENTRIES]->type &= ~IPF_REVERSE;
  1949.             entry[sel/ENTRIES]->type |= reverse;
  1950.         }
  1951.         else if ((sel % ENTRIES) == 2)
  1952.         /* sensitivity */
  1953.         {
  1954.             int val = IP_GET_SENSITIVITY(entry[sel/ENTRIES]);
  1955.  
  1956.             val --;
  1957.             if (val < 1) val = 1;
  1958.             IP_SET_SENSITIVITY(entry[sel/ENTRIES],val);
  1959.         }
  1960.     }
  1961.  
  1962.     if (input_ui_pressed_repeat(IPT_UI_RIGHT,8))
  1963.     {
  1964.         if ((sel % ENTRIES) == 0)
  1965.         /* keyboard/joystick delta */
  1966.         {
  1967.             int val = IP_GET_DELTA(entry[sel/ENTRIES]);
  1968.  
  1969.             val ++;
  1970.             if (val > 255) val = 255;
  1971.             IP_SET_DELTA(entry[sel/ENTRIES],val);
  1972.         }
  1973.         else if ((sel % ENTRIES) == 1)
  1974.         /* reverse */
  1975.         {
  1976.             int reverse = entry[sel/ENTRIES]->type & IPF_REVERSE;
  1977.             if (reverse)
  1978.                 reverse=0;
  1979.             else
  1980.                 reverse=IPF_REVERSE;
  1981.             entry[sel/ENTRIES]->type &= ~IPF_REVERSE;
  1982.             entry[sel/ENTRIES]->type |= reverse;
  1983.         }
  1984.         else if ((sel % ENTRIES) == 2)
  1985.         /* sensitivity */
  1986.         {
  1987.             int val = IP_GET_SENSITIVITY(entry[sel/ENTRIES]);
  1988.  
  1989.             val ++;
  1990.             if (val > 255) val = 255;
  1991.             IP_SET_SENSITIVITY(entry[sel/ENTRIES],val);
  1992.         }
  1993.     }
  1994.  
  1995.     if (input_ui_pressed(IPT_UI_SELECT))
  1996.     {
  1997.         if (sel == total2 - 1) sel = -1;
  1998.     }
  1999.  
  2000.     if (input_ui_pressed(IPT_UI_CANCEL))
  2001.         sel = -1;
  2002.  
  2003.     if (input_ui_pressed(IPT_UI_CONFIGURE))
  2004.         sel = -2;
  2005.  
  2006.     if (sel == -1 || sel == -2)
  2007.     {
  2008.         /* tell updatescreen() to clean after us */
  2009.         need_to_clear_bitmap = 1;
  2010.     }
  2011.  
  2012.     return sel + 1;
  2013. }
  2014.  
  2015. #ifndef MESS
  2016. static int mame_stats(struct osd_bitmap *bitmap,int selected)
  2017. {
  2018.     char temp[10];
  2019.     char buf[2048];
  2020.     int sel, i;
  2021.  
  2022.  
  2023.     sel = selected - 1;
  2024.  
  2025.     buf[0] = 0;
  2026.  
  2027.     if (dispensed_tickets)
  2028.     {
  2029.         strcat(buf, ui_getstring (UI_tickets));
  2030.         strcat(buf, ": ");
  2031.         sprintf(temp, "%d\n\n", dispensed_tickets);
  2032.         strcat(buf, temp);
  2033.     }
  2034.  
  2035.     for (i=0; i<COIN_COUNTERS; i++)
  2036.     {
  2037.         strcat(buf, ui_getstring (UI_coin));
  2038.         sprintf(temp, " %c: ", i+'A');
  2039.         strcat(buf, temp);
  2040.         if (!coins[i])
  2041.             strcat (buf, ui_getstring (UI_NA));
  2042.         else
  2043.         {
  2044.             sprintf (temp, "%d", coins[i]);
  2045.             strcat (buf, temp);
  2046.         }
  2047.         if (coinlockedout[i])
  2048.         {
  2049.             strcat(buf, " ");
  2050.             strcat(buf, ui_getstring (UI_locked));
  2051.             strcat(buf, "\n");
  2052.         }
  2053.         else
  2054.         {
  2055.             strcat(buf, "\n");
  2056.         }
  2057.     }
  2058.  
  2059.     {
  2060.         /* menu system, use the normal menu keys */
  2061.         strcat(buf,"\n\t");
  2062.         strcat(buf,ui_getstring (UI_lefthilight));
  2063.         strcat(buf," ");
  2064.         strcat(buf,ui_getstring (UI_returntomain));
  2065.         strcat(buf," ");
  2066.         strcat(buf,ui_getstring (UI_righthilight));
  2067.  
  2068.         ui_displaymessagewindow(bitmap,buf);
  2069.  
  2070.         if (input_ui_pressed(IPT_UI_SELECT))
  2071.             sel = -1;
  2072.  
  2073.         if (input_ui_pressed(IPT_UI_CANCEL))
  2074.             sel = -1;
  2075.  
  2076.         if (input_ui_pressed(IPT_UI_CONFIGURE))
  2077.             sel = -2;
  2078.     }
  2079.  
  2080.     if (sel == -1 || sel == -2)
  2081.     {
  2082.         /* tell updatescreen() to clean after us */
  2083.         need_to_clear_bitmap = 1;
  2084.     }
  2085.  
  2086.     return sel + 1;
  2087. }
  2088. #endif
  2089.  
  2090. int showcopyright(struct osd_bitmap *bitmap)
  2091. {
  2092.     int done;
  2093.     char buf[1000];
  2094.     char buf2[256];
  2095.  
  2096.     strcpy (buf, ui_getstring(UI_copyright1));
  2097.     strcat (buf, "\n\n");
  2098.     sprintf(buf2, ui_getstring(UI_copyright2), Machine->gamedrv->description);
  2099.     strcat (buf, buf2);
  2100.     strcat (buf, "\n\n");
  2101.     strcat (buf, ui_getstring(UI_copyright3));
  2102.  
  2103.     ui_displaymessagewindow(bitmap,buf);
  2104.  
  2105.     setup_selected = -1;////
  2106.     done = 0;
  2107.     do
  2108.     {
  2109.         update_video_and_audio();
  2110.         osd_poll_joysticks();
  2111.         if (input_ui_pressed(IPT_UI_CANCEL))
  2112.         {
  2113.             setup_selected = 0;////
  2114.             return 1;
  2115.         }
  2116.         if (keyboard_pressed_memory(KEYCODE_O) ||
  2117.                 input_ui_pressed(IPT_UI_LEFT))
  2118.             done = 1;
  2119.         if (done == 1 && (keyboard_pressed_memory(KEYCODE_K) ||
  2120.                 input_ui_pressed(IPT_UI_RIGHT)))
  2121.             done = 2;
  2122.     } while (done < 2);
  2123.  
  2124.     setup_selected = 0;////
  2125.     osd_clearbitmap(bitmap);
  2126.     update_video_and_audio();
  2127.  
  2128.     return 0;
  2129. }
  2130.  
  2131. static int displaygameinfo(struct osd_bitmap *bitmap,int selected)
  2132. {
  2133.     int i;
  2134.     char buf[2048];
  2135.     char buf2[32];
  2136.     int sel;
  2137.  
  2138.  
  2139.     sel = selected - 1;
  2140.  
  2141.  
  2142.     sprintf(buf,"%s\n%s %s\n\n%s:\n",Machine->gamedrv->description,Machine->gamedrv->year,Machine->gamedrv->manufacturer,
  2143.         ui_getstring (UI_cpu));
  2144.     i = 0;
  2145.     while (i < MAX_CPU && Machine->drv->cpu[i].cpu_type)
  2146.     {
  2147.  
  2148.         if (Machine->drv->cpu[i].cpu_clock >= 1000000)
  2149.             sprintf(&buf[strlen(buf)],"%s %d.%06d MHz",
  2150.                     cputype_name(Machine->drv->cpu[i].cpu_type),
  2151.                     Machine->drv->cpu[i].cpu_clock / 1000000,
  2152.                     Machine->drv->cpu[i].cpu_clock % 1000000);
  2153.         else
  2154.             sprintf(&buf[strlen(buf)],"%s %d.%03d kHz",
  2155.                     cputype_name(Machine->drv->cpu[i].cpu_type),
  2156.                     Machine->drv->cpu[i].cpu_clock / 1000,
  2157.                     Machine->drv->cpu[i].cpu_clock % 1000);
  2158.  
  2159.         if (Machine->drv->cpu[i].cpu_type & CPU_AUDIO_CPU)
  2160.         {
  2161.             sprintf (buf2, " (%s)", ui_getstring (UI_sound_lc));
  2162.             strcat(buf, buf2);
  2163.         }
  2164.  
  2165.         strcat(buf,"\n");
  2166.  
  2167.         i++;
  2168.     }
  2169.  
  2170.     sprintf (buf2, "\n%s", ui_getstring (UI_sound));
  2171.     strcat (buf, buf2);
  2172.     if (Machine->drv->sound_attributes & SOUND_SUPPORTS_STEREO)
  2173.         sprintf(&buf[strlen(buf)]," (%s)", ui_getstring (UI_stereo));
  2174.     strcat(buf,":\n");
  2175.  
  2176.     i = 0;
  2177.     while (i < MAX_SOUND && Machine->drv->sound[i].sound_type)
  2178.     {
  2179.         if (sound_num(&Machine->drv->sound[i]))
  2180.             sprintf(&buf[strlen(buf)],"%dx",sound_num(&Machine->drv->sound[i]));
  2181.  
  2182.         sprintf(&buf[strlen(buf)],"%s",sound_name(&Machine->drv->sound[i]));
  2183.  
  2184.         if (sound_clock(&Machine->drv->sound[i]))
  2185.         {
  2186.             if (sound_clock(&Machine->drv->sound[i]) >= 1000000)
  2187.                 sprintf(&buf[strlen(buf)]," %d.%06d MHz",
  2188.                         sound_clock(&Machine->drv->sound[i]) / 1000000,
  2189.                         sound_clock(&Machine->drv->sound[i]) % 1000000);
  2190.             else
  2191.                 sprintf(&buf[strlen(buf)]," %d.%03d kHz",
  2192.                         sound_clock(&Machine->drv->sound[i]) / 1000,
  2193.                         sound_clock(&Machine->drv->sound[i]) % 1000);
  2194.         }
  2195.  
  2196.         strcat(buf,"\n");
  2197.  
  2198.         i++;
  2199.     }
  2200.  
  2201.     if (Machine->drv->video_attributes & VIDEO_TYPE_VECTOR)
  2202.         sprintf(&buf[strlen(buf)],"\n%s\n", ui_getstring (UI_vectorgame));
  2203.     else
  2204.     {
  2205.         int pixelx,pixely,tmax,tmin,rem;
  2206.  
  2207.         pixelx = 4 * (Machine->drv->visible_area.max_y - Machine->drv->visible_area.min_y + 1);
  2208.         pixely = 3 * (Machine->drv->visible_area.max_x - Machine->drv->visible_area.min_x + 1);
  2209.  
  2210.         /* calculate MCD */
  2211.         if (pixelx >= pixely)
  2212.         {
  2213.             tmax = pixelx;
  2214.             tmin = pixely;
  2215.         }
  2216.         else
  2217.         {
  2218.             tmax = pixely;
  2219.             tmin = pixelx;
  2220.         }
  2221.         while ( (rem = tmax % tmin) )
  2222.         {
  2223.             tmax = tmin;
  2224.             tmin = rem;
  2225.         }
  2226.         /* tmin is now the MCD */
  2227.  
  2228.         pixelx /= tmin;
  2229.         pixely /= tmin;
  2230.  
  2231.         sprintf(&buf[strlen(buf)],"\n%s:\n", ui_getstring (UI_screenres));
  2232.         sprintf(&buf[strlen(buf)],"%d x %d (%s) %f Hz\n",
  2233.                 Machine->drv->visible_area.max_x - Machine->drv->visible_area.min_x + 1,
  2234.                 Machine->drv->visible_area.max_y - Machine->drv->visible_area.min_y + 1,
  2235.                 (Machine->gamedrv->flags & ORIENTATION_SWAP_XY) ? "V" : "H",
  2236.                 Machine->drv->frames_per_second);
  2237. #if 0
  2238.         sprintf(&buf[strlen(buf)],"pixel aspect ratio %d:%d\n",
  2239.                 pixelx,pixely);
  2240.         sprintf(&buf[strlen(buf)],"%d colors ",Machine->drv->total_colors);
  2241.         if (Machine->gamedrv->flags & GAME_REQUIRES_16BIT)
  2242.             strcat(buf,"(16-bit required)\n");
  2243.         else if (Machine->drv->video_attributes & VIDEO_MODIFIES_PALETTE)
  2244.             strcat(buf,"(dynamic)\n");
  2245.         else strcat(buf,"(static)\n");
  2246. #endif
  2247.     }
  2248.  
  2249.  
  2250.     if (sel == -1)
  2251.     {
  2252.         /* startup info, print MAME version and ask for any key */
  2253.  
  2254.         sprintf (buf2, "\n\t%s ", ui_getstring (UI_mame));    /* \t means that the line will be centered */
  2255.         strcat(buf, buf2);
  2256.  
  2257.         strcat(buf,build_version);
  2258.         sprintf (buf2, "\n\t%s", ui_getstring (UI_anykey));
  2259.         strcat(buf,buf2);
  2260.         ui_drawbox(bitmap,0,0,Machine->uiwidth,Machine->uiheight);
  2261.         ui_displaymessagewindow(bitmap,buf);
  2262.  
  2263.         sel = 0;
  2264.         if (code_read_async() != CODE_NONE)
  2265.             sel = -1;
  2266.     }
  2267.     else
  2268.     {
  2269.         /* menu system, use the normal menu keys */
  2270.         strcat(buf,"\n\t");
  2271.         strcat(buf,ui_getstring (UI_lefthilight));
  2272.         strcat(buf," ");
  2273.         strcat(buf,ui_getstring (UI_returntomain));
  2274.         strcat(buf," ");
  2275.         strcat(buf,ui_getstring (UI_righthilight));
  2276.  
  2277.         ui_displaymessagewindow(bitmap,buf);
  2278.  
  2279.         if (input_ui_pressed(IPT_UI_SELECT))
  2280.             sel = -1;
  2281.  
  2282.         if (input_ui_pressed(IPT_UI_CANCEL))
  2283.             sel = -1;
  2284.  
  2285.         if (input_ui_pressed(IPT_UI_CONFIGURE))
  2286.             sel = -2;
  2287.     }
  2288.  
  2289.     if (sel == -1 || sel == -2)
  2290.     {
  2291.         /* tell updatescreen() to clean after us */
  2292.         need_to_clear_bitmap = 1;
  2293.     }
  2294.  
  2295.     return sel + 1;
  2296. }
  2297.  
  2298.  
  2299. int showgamewarnings(struct osd_bitmap *bitmap)
  2300. {
  2301.     int i;
  2302.     char buf[2048];
  2303.  
  2304.     if (Machine->gamedrv->flags &
  2305.             (GAME_NOT_WORKING | GAME_UNEMULATED_PROTECTION | GAME_WRONG_COLORS | GAME_IMPERFECT_COLORS |
  2306.               GAME_NO_SOUND | GAME_IMPERFECT_SOUND | GAME_NO_COCKTAIL))
  2307.     {
  2308.         int done;
  2309.  
  2310.         strcpy(buf, ui_getstring (UI_knownproblems));
  2311.         strcat(buf, "\n\n");
  2312.  
  2313. #ifdef MESS
  2314.         if (Machine->gamedrv->flags & GAME_COMPUTER)
  2315.         {
  2316.             strcpy(buf, ui_getstring (UI_comp1));
  2317.             strcat(buf, "\n\n");
  2318.             strcat(buf, ui_getstring (UI_comp2));
  2319.             strcat(buf, "\n");
  2320.         }
  2321. #endif
  2322.  
  2323.         if (Machine->gamedrv->flags & GAME_IMPERFECT_COLORS)
  2324.         {
  2325.             strcat(buf, ui_getstring (UI_imperfectcolors));
  2326.             strcat(buf, "\n");
  2327.         }
  2328.  
  2329.         if (Machine->gamedrv->flags & GAME_WRONG_COLORS)
  2330.         {
  2331.             strcat(buf, ui_getstring (UI_wrongcolors));
  2332.             strcat(buf, "\n");
  2333.         }
  2334.  
  2335.         if (Machine->gamedrv->flags & GAME_IMPERFECT_SOUND)
  2336.         {
  2337.             strcat(buf, ui_getstring (UI_imperfectsound));
  2338.             strcat(buf, "\n");
  2339.         }
  2340.  
  2341.         if (Machine->gamedrv->flags & GAME_NO_SOUND)
  2342.         {
  2343.             strcat(buf, ui_getstring (UI_nosound));
  2344.             strcat(buf, "\n");
  2345.         }
  2346.  
  2347.         if (Machine->gamedrv->flags & GAME_NO_COCKTAIL)
  2348.         {
  2349.             strcat(buf, ui_getstring (UI_nococktail));
  2350.             strcat(buf, "\n");
  2351.         }
  2352.  
  2353.         if (Machine->gamedrv->flags & (GAME_NOT_WORKING | GAME_UNEMULATED_PROTECTION))
  2354.         {
  2355.             const struct GameDriver *maindrv;
  2356.             int foundworking;
  2357.  
  2358.             if (Machine->gamedrv->flags & GAME_NOT_WORKING)
  2359.                 strcpy(buf, ui_getstring (UI_brokengame));
  2360.             if (Machine->gamedrv->flags & GAME_UNEMULATED_PROTECTION)
  2361.                 strcat(buf, ui_getstring (UI_brokenprotection));
  2362.  
  2363.             if (Machine->gamedrv->clone_of && !(Machine->gamedrv->clone_of->flags & NOT_A_DRIVER))
  2364.                 maindrv = Machine->gamedrv->clone_of;
  2365.             else maindrv = Machine->gamedrv;
  2366.  
  2367.             foundworking = 0;
  2368.             i = 0;
  2369.             while (drivers[i])
  2370.             {
  2371.                 if (drivers[i] == maindrv || drivers[i]->clone_of == maindrv)
  2372.                 {
  2373.                     if ((drivers[i]->flags & (GAME_NOT_WORKING | GAME_UNEMULATED_PROTECTION)) == 0)
  2374.                     {
  2375.                         if (foundworking == 0)
  2376.                         {
  2377.                             strcat(buf,"\n\n");
  2378.                             strcat(buf, ui_getstring (UI_workingclones));
  2379.                             strcat(buf,"\n\n");
  2380.                         }
  2381.                         foundworking = 1;
  2382.  
  2383.                         sprintf(&buf[strlen(buf)],"%s\n",drivers[i]->name);
  2384.                     }
  2385.                 }
  2386.                 i++;
  2387.             }
  2388.         }
  2389.  
  2390.         strcat(buf,"\n\n");
  2391.         strcat(buf,ui_getstring (UI_typeok));
  2392.  
  2393.         ui_displaymessagewindow(bitmap,buf);
  2394.  
  2395.         done = 0;
  2396.         do
  2397.         {
  2398.             update_video_and_audio();
  2399.             osd_poll_joysticks();
  2400.             if (input_ui_pressed(IPT_UI_CANCEL))
  2401.                 return 1;
  2402.             if (code_pressed_memory(KEYCODE_O) ||
  2403.                     input_ui_pressed(IPT_UI_LEFT))
  2404.                 done = 1;
  2405.             if (done == 1 && (code_pressed_memory(KEYCODE_K) ||
  2406.                     input_ui_pressed(IPT_UI_RIGHT)))
  2407.                 done = 2;
  2408.         } while (done < 2);
  2409.     }
  2410.  
  2411.  
  2412.     osd_clearbitmap(bitmap);
  2413.  
  2414.     /* clear the input memory */
  2415.     while (code_read_async() != CODE_NONE) {};
  2416.  
  2417.     while (displaygameinfo(bitmap,0) == 1)
  2418.     {
  2419.         update_video_and_audio();
  2420.         osd_poll_joysticks();
  2421.     }
  2422.  
  2423.     #ifdef MESS
  2424.     while (displayimageinfo(bitmap,0) == 1)
  2425.     {
  2426.         update_video_and_audio();
  2427.         osd_poll_joysticks();
  2428.     }
  2429.     #endif
  2430.  
  2431.     osd_clearbitmap(bitmap);
  2432.     /* make sure that the screen is really cleared, in case autoframeskip kicked in */
  2433.     update_video_and_audio();
  2434.     update_video_and_audio();
  2435.     update_video_and_audio();
  2436.     update_video_and_audio();
  2437.  
  2438.     return 0;
  2439. }
  2440.  
  2441. /* Word-wraps the text in the specified buffer to fit in maxwidth characters per line.
  2442.    The contents of the buffer are modified.
  2443.    Known limitations: Words longer than maxwidth cause the function to fail. */
  2444. static void wordwrap_text_buffer (char *buffer, int maxwidth)
  2445. {
  2446.     int width = 0;
  2447.  
  2448.     while (*buffer)
  2449.     {
  2450.         if (*buffer == '\n')
  2451.         {
  2452.             buffer++;
  2453.             width = 0;
  2454.             continue;
  2455.         }
  2456.  
  2457.         width++;
  2458.  
  2459.         if (width > maxwidth)
  2460.         {
  2461.             /* backtrack until a space is found */
  2462.             while (*buffer != ' ')
  2463.             {
  2464.                 buffer--;
  2465.                 width--;
  2466.             }
  2467.             if (width < 1) return;    /* word too long */
  2468.  
  2469.             /* replace space with a newline */
  2470.             *buffer = '\n';
  2471.         }
  2472.         else
  2473.             buffer++;
  2474.     }
  2475. }
  2476.  
  2477. static int count_lines_in_buffer (char *buffer)
  2478. {
  2479.     int lines = 0;
  2480.     char c;
  2481.  
  2482.     while ( (c = *buffer++) )
  2483.         if (c == '\n') lines++;
  2484.  
  2485.     return lines;
  2486. }
  2487.  
  2488. /* Display lines from buffer, starting with line 'scroll', in a width x height text window */
  2489. static void display_scroll_message (struct osd_bitmap *bitmap, int *scroll, int width, int height, char *buf)
  2490. {
  2491.     struct DisplayText dt[256];
  2492.     int curr_dt = 0;
  2493.     const char *uparrow = ui_getstring (UI_uparrow);
  2494.     const char *downarrow = ui_getstring (UI_downarrow);
  2495.     char textcopy[2048];
  2496.     char *copy;
  2497.     int leftoffs,topoffs;
  2498.     int first = *scroll;
  2499.     int buflines,showlines;
  2500.     int i;
  2501.  
  2502.  
  2503.     /* draw box */
  2504.     leftoffs = (Machine->uiwidth - Machine->uifontwidth * (width + 1)) / 2;
  2505.     if (leftoffs < 0) leftoffs = 0;
  2506.     topoffs = (Machine->uiheight - (3 * height + 1) * Machine->uifontheight / 2) / 2;
  2507.     ui_drawbox(bitmap,leftoffs,topoffs,(width + 1) * Machine->uifontwidth,(3 * height + 1) * Machine->uifontheight / 2);
  2508.  
  2509.     buflines = count_lines_in_buffer (buf);
  2510.     if (first > 0)
  2511.     {
  2512.         if (buflines <= height)
  2513.             first = 0;
  2514.         else
  2515.         {
  2516.             height--;
  2517.             if (first > (buflines - height))
  2518.                 first = buflines - height;
  2519.         }
  2520.         *scroll = first;
  2521.     }
  2522.  
  2523.     if (first != 0)
  2524.     {
  2525.         /* indicate that scrolling upward is possible */
  2526.         dt[curr_dt].text = uparrow;
  2527.         dt[curr_dt].color = UI_COLOR_NORMAL;
  2528.         dt[curr_dt].x = (Machine->uiwidth - Machine->uifontwidth * strlen(uparrow)) / 2;
  2529.         dt[curr_dt].y = topoffs + (3*curr_dt+1)*Machine->uifontheight/2;
  2530.         curr_dt++;
  2531.     }
  2532.  
  2533.     if ((buflines - first) > height)
  2534.         showlines = height - 1;
  2535.     else
  2536.         showlines = height;
  2537.  
  2538.     /* skip to first line */
  2539.     while (first > 0)
  2540.     {
  2541.         char c;
  2542.  
  2543.         while ( (c = *buf++) )
  2544.         {
  2545.             if (c == '\n')
  2546.             {
  2547.                 first--;
  2548.                 break;
  2549.             }
  2550.         }
  2551.     }
  2552.  
  2553.     /* copy 'showlines' lines from buffer, starting with line 'first' */
  2554.     copy = textcopy;
  2555.     for (i = 0; i < showlines; i++)
  2556.     {
  2557.         char *copystart = copy;
  2558.  
  2559.         while (*buf && *buf != '\n')
  2560.         {
  2561.             *copy = *buf;
  2562.             copy++;
  2563.             buf++;
  2564.         }
  2565.         *copy = '\0';
  2566.         copy++;
  2567.         if (*buf == '\n')
  2568.             buf++;
  2569.  
  2570.         if (*copystart == '\t') /* center text */
  2571.         {
  2572.             copystart++;
  2573.             dt[curr_dt].x = (Machine->uiwidth - Machine->uifontwidth * (copy - copystart)) / 2;
  2574.         }
  2575.         else
  2576.             dt[curr_dt].x = leftoffs + Machine->uifontwidth/2;
  2577.  
  2578.         dt[curr_dt].text = copystart;
  2579.         dt[curr_dt].color = UI_COLOR_NORMAL;
  2580.         dt[curr_dt].y = topoffs + (3*curr_dt+1)*Machine->uifontheight/2;
  2581.         curr_dt++;
  2582.     }
  2583.  
  2584.     if (showlines == (height - 1))
  2585.     {
  2586.         /* indicate that scrolling downward is possible */
  2587.         dt[curr_dt].text = downarrow;
  2588.         dt[curr_dt].color = UI_COLOR_NORMAL;
  2589.         dt[curr_dt].x = (Machine->uiwidth - Machine->uifontwidth * strlen(downarrow)) / 2;
  2590.         dt[curr_dt].y = topoffs + (3*curr_dt+1)*Machine->uifontheight/2;
  2591.         curr_dt++;
  2592.     }
  2593.  
  2594.     dt[curr_dt].text = 0;    /* terminate array */
  2595.  
  2596.     displaytext(bitmap,dt,0,0);
  2597. }
  2598.  
  2599.  
  2600. /* Display text entry for current driver from history.dat and mameinfo.dat. */
  2601. static int displayhistory (struct osd_bitmap *bitmap, int selected)
  2602. {
  2603.     static int scroll = 0;
  2604.     static char *buf = 0;
  2605.     int maxcols,maxrows;
  2606.     int sel;
  2607.  
  2608.  
  2609.     sel = selected - 1;
  2610.  
  2611.  
  2612.     maxcols = (Machine->uiwidth / Machine->uifontwidth) - 1;
  2613.     maxrows = (2 * Machine->uiheight - Machine->uifontheight) / (3 * Machine->uifontheight);
  2614.     maxcols -= 2;
  2615.     maxrows -= 8;
  2616.  
  2617.     if (!buf)
  2618.     {
  2619.         /* allocate a buffer for the text */
  2620.         buf = malloc (8192);
  2621.         if (buf)
  2622.         {
  2623.             /* try to load entry */
  2624.             if (load_driver_history (Machine->gamedrv, buf, 8192) == 0)
  2625.             {
  2626.                 scroll = 0;
  2627.                 wordwrap_text_buffer (buf, maxcols);
  2628.                 strcat(buf,"\n\t");
  2629.                 strcat(buf,ui_getstring (UI_lefthilight));
  2630.                 strcat(buf," ");
  2631.                 strcat(buf,ui_getstring (UI_returntomain));
  2632.                 strcat(buf," ");
  2633.                 strcat(buf,ui_getstring (UI_righthilight));
  2634.                 strcat(buf,"\n");
  2635.             }
  2636.             else
  2637.             {
  2638.                 free (buf);
  2639.                 buf = 0;
  2640.             }
  2641.         }
  2642.     }
  2643.  
  2644.     {
  2645.         if (buf)
  2646.             display_scroll_message (bitmap, &scroll, maxcols, maxrows, buf);
  2647.         else
  2648.         {
  2649.             char msg[80];
  2650.  
  2651.             strcpy (msg, "\t");
  2652.             strcat (msg, ui_getstring(UI_historymissing));
  2653.             strcat (msg, "\n\n\t");
  2654.             strcat(buf,ui_getstring (UI_lefthilight));
  2655.             strcat(buf," ");
  2656.             strcat(buf,ui_getstring (UI_returntomain));
  2657.             strcat(buf," ");
  2658.             strcat(buf,ui_getstring (UI_righthilight));
  2659.             ui_displaymessagewindow (bitmap,msg);
  2660.         }
  2661.  
  2662.         if ((scroll > 0) && input_ui_pressed_repeat(IPT_UI_UP,4))
  2663.         {
  2664.             if (scroll == 2) scroll = 0;    /* 1 would be the same as 0, but with arrow on top */
  2665.             else scroll--;
  2666.         }
  2667.  
  2668.         if (input_ui_pressed_repeat(IPT_UI_DOWN,4))
  2669.         {
  2670.             if (scroll == 0) scroll = 2;    /* 1 would be the same as 0, but with arrow on top */
  2671.             else scroll++;
  2672.         }
  2673.  
  2674.         if (input_ui_pressed(IPT_UI_SELECT))
  2675.             sel = -1;
  2676.  
  2677.         if (input_ui_pressed(IPT_UI_CANCEL))
  2678.             sel = -1;
  2679.  
  2680.         if (input_ui_pressed(IPT_UI_CONFIGURE))
  2681.             sel = -2;
  2682.     }
  2683.  
  2684.     if (sel == -1 || sel == -2)
  2685.     {
  2686.         /* tell updatescreen() to clean after us */
  2687.         need_to_clear_bitmap = 1;
  2688.  
  2689.         /* force buffer to be recreated */
  2690.         if (buf)
  2691.         {
  2692.             free (buf);
  2693.             buf = 0;
  2694.         }
  2695.     }
  2696.  
  2697.     return sel + 1;
  2698.  
  2699. }
  2700.  
  2701.  
  2702. #ifndef NEOFREE
  2703. #ifndef TINY_COMPILE
  2704. int memcard_menu(struct osd_bitmap *bitmap, int selection)
  2705. {
  2706.     int sel;
  2707.     int menutotal = 0;
  2708.     const char *menuitem[10];
  2709.     char buf[256];
  2710.     char buf2[256];
  2711.  
  2712.     sel = selection - 1 ;
  2713.  
  2714.     sprintf(buf, "%s %03d", ui_getstring (UI_loadcard), mcd_number);
  2715.     menuitem[menutotal++] = buf;
  2716.     menuitem[menutotal++] = ui_getstring (UI_ejectcard);
  2717.     menuitem[menutotal++] = ui_getstring (UI_createcard);
  2718.     menuitem[menutotal++] = ui_getstring (UI_resetcard);
  2719.     menuitem[menutotal++] = ui_getstring (UI_returntomain);
  2720.     menuitem[menutotal] = 0;
  2721.  
  2722.     if (mcd_action!=0)
  2723.     {
  2724.         strcpy (buf2, "\n");
  2725.  
  2726.         switch(mcd_action)
  2727.         {
  2728.             case 1:
  2729.                 strcat (buf2, ui_getstring (UI_loadfailed));
  2730.                 break;
  2731.             case 2:
  2732.                 strcat (buf2, ui_getstring (UI_loadok));
  2733.                 break;
  2734.             case 3:
  2735.                 strcat (buf2, ui_getstring (UI_cardejected));
  2736.                 break;
  2737.             case 4:
  2738.                 strcat (buf2, ui_getstring (UI_cardcreated));
  2739.                 break;
  2740.             case 5:
  2741.                 strcat (buf2, ui_getstring (UI_cardcreatedfailed));
  2742.                 strcat (buf2, "\n");
  2743.                 strcat (buf2, ui_getstring (UI_cardcreatedfailed2));
  2744.                 break;
  2745.             default:
  2746.                 strcat (buf2, ui_getstring (UI_carderror));
  2747.                 break;
  2748.         }
  2749.  
  2750.         strcat (buf2, "\n\n");
  2751.         ui_displaymessagewindow(bitmap,buf2);
  2752.         if (input_ui_pressed(IPT_UI_SELECT))
  2753.             mcd_action = 0;
  2754.     }
  2755.     else
  2756.     {
  2757.         ui_displaymenu(bitmap,menuitem,0,0,sel,0);
  2758.  
  2759.         if (input_ui_pressed_repeat(IPT_UI_RIGHT,8))
  2760.             mcd_number = (mcd_number + 1) % 1000;
  2761.  
  2762.         if (input_ui_pressed_repeat(IPT_UI_LEFT,8))
  2763.             mcd_number = (mcd_number + 999) % 1000;
  2764.  
  2765.         if (input_ui_pressed_repeat(IPT_UI_DOWN,8))
  2766.             sel = (sel + 1) % menutotal;
  2767.  
  2768.         if (input_ui_pressed_repeat(IPT_UI_UP,8))
  2769.             sel = (sel + menutotal - 1) % menutotal;
  2770.  
  2771.         if (input_ui_pressed(IPT_UI_SELECT))
  2772.         {
  2773.             switch(sel)
  2774.             {
  2775.             case 0:
  2776.                 neogeo_memcard_eject();
  2777.                 if (neogeo_memcard_load(mcd_number))
  2778.                 {
  2779.                     memcard_status=1;
  2780.                     memcard_number=mcd_number;
  2781.                     mcd_action = 2;
  2782.                 }
  2783.                 else
  2784.                     mcd_action = 1;
  2785.                 break;
  2786.             case 1:
  2787.                 neogeo_memcard_eject();
  2788.                 mcd_action = 3;
  2789.                 break;
  2790.             case 2:
  2791.                 if (neogeo_memcard_create(mcd_number))
  2792.                     mcd_action = 4;
  2793.                 else
  2794.                     mcd_action = 5;
  2795.                 break;
  2796.             case 3:
  2797.                 memcard_manager=1;
  2798.                 sel=-2;
  2799.                 machine_reset();
  2800.                 break;
  2801.             case 4:
  2802.                 sel=-1;
  2803.                 break;
  2804.             }
  2805.         }
  2806.  
  2807.         if (input_ui_pressed(IPT_UI_CANCEL))
  2808.             sel = -1;
  2809.  
  2810.         if (input_ui_pressed(IPT_UI_CONFIGURE))
  2811.             sel = -2;
  2812.  
  2813.         if (sel == -1 || sel == -2)
  2814.         {
  2815.             /* tell updatescreen() to clean after us */
  2816.             need_to_clear_bitmap = 1;
  2817.         }
  2818.     }
  2819.  
  2820.     return sel + 1;
  2821. }
  2822. #endif
  2823. #endif
  2824.  
  2825.  
  2826. #ifndef MESS
  2827. enum { UI_SWITCH = 0,UI_DEFCODE,UI_CODE,UI_ANALOG,UI_CALIBRATE,
  2828.         UI_STATS,UI_GAMEINFO, UI_HISTORY,
  2829.         UI_CHEAT,UI_RESET,UI_MEMCARD,UI_EXIT };
  2830. #else
  2831. enum { UI_SWITCH = 0,UI_DEFCODE,UI_CODE,UI_ANALOG,UI_CALIBRATE,
  2832.         UI_GAMEINFO, UI_IMAGEINFO,UI_FILEMANAGER,UI_TAPECONTROL,
  2833.         UI_HISTORY,UI_CHEAT,UI_RESET,UI_MEMCARD,UI_EXIT };
  2834. #endif
  2835.  
  2836.  
  2837. #define MAX_SETUPMENU_ITEMS 20
  2838. static const char *menu_item[MAX_SETUPMENU_ITEMS];
  2839. static int menu_action[MAX_SETUPMENU_ITEMS];
  2840. static int menu_total;
  2841.  
  2842.  
  2843. static void setup_menu_init(void)
  2844. {
  2845.     menu_total = 0;
  2846.  
  2847.     menu_item[menu_total] = ui_getstring (UI_inputgeneral); menu_action[menu_total++] = UI_DEFCODE;
  2848.     menu_item[menu_total] = ui_getstring (UI_inputspecific); menu_action[menu_total++] = UI_CODE;
  2849.     menu_item[menu_total] = ui_getstring (UI_dipswitches); menu_action[menu_total++] = UI_SWITCH;
  2850.  
  2851.     /* Determine if there are any analog controls */
  2852.     {
  2853.         struct InputPort *in;
  2854.         int num;
  2855.  
  2856.         in = Machine->input_ports;
  2857.  
  2858.         num = 0;
  2859.         while (in->type != IPT_END)
  2860.         {
  2861.             if (((in->type & 0xff) > IPT_ANALOG_START) && ((in->type & 0xff) < IPT_ANALOG_END)
  2862.                     && !(!options.cheat && (in->type & IPF_CHEAT)))
  2863.                 num++;
  2864.             in++;
  2865.         }
  2866.  
  2867.         if (num != 0)
  2868.         {
  2869.             menu_item[menu_total] = ui_getstring (UI_analogcontrols); menu_action[menu_total++] = UI_ANALOG;
  2870.         }
  2871.     }
  2872.  
  2873.     /* Joystick calibration possible? */
  2874.     if ((osd_joystick_needs_calibration()) != 0)
  2875.     {
  2876.         menu_item[menu_total] = ui_getstring (UI_calibrate); menu_action[menu_total++] = UI_CALIBRATE;
  2877.     }
  2878.  
  2879.     menu_item[menu_total] = ui_getstring (UI_bookkeeping); menu_action[menu_total++] = UI_STATS;
  2880.     menu_item[menu_total] = ui_getstring (UI_gameinfo); menu_action[menu_total++] = UI_GAMEINFO;
  2881.     menu_item[menu_total] = ui_getstring (UI_history); menu_action[menu_total++] = UI_HISTORY;
  2882. #ifdef MESS
  2883.     menu_item[menu_total] = ui_getstring (UI_imageinfo); menu_action[menu_total++] = UI_IMAGEINFO;
  2884.     menu_item[menu_total] = ui_getstring (UI_filemanager); menu_action[menu_total++] = UI_FILEMANAGER;
  2885.     menu_item[menu_total] = ui_getstring (UI_tapecontrol); menu_action[menu_total++] = UI_TAPECONTROL;
  2886. #endif
  2887.  
  2888.     if (options.cheat)
  2889.     {
  2890.         menu_item[menu_total] = ui_getstring (UI_cheat); menu_action[menu_total++] = UI_CHEAT;
  2891.     }
  2892.  
  2893. #ifndef NEOFREE
  2894. #ifndef TINY_COMPILE
  2895.     if (Machine->gamedrv->clone_of == &driver_neogeo ||
  2896.             (Machine->gamedrv->clone_of &&
  2897.                 Machine->gamedrv->clone_of->clone_of == &driver_neogeo))
  2898.     {
  2899.         menu_item[menu_total] = ui_getstring (UI_memorycard); menu_action[menu_total++] = UI_MEMCARD;
  2900.     }
  2901. #endif
  2902. #endif
  2903.  
  2904.     menu_item[menu_total] = ui_getstring (UI_resetgame); menu_action[menu_total++] = UI_RESET;
  2905.     menu_item[menu_total] = ui_getstring (UI_returntogame); menu_action[menu_total++] = UI_EXIT;
  2906.     menu_item[menu_total] = 0; /* terminate array */
  2907. }
  2908.  
  2909.  
  2910. static int setup_menu(struct osd_bitmap *bitmap, int selected)
  2911. {
  2912.     int sel,res=-1;
  2913.     static int menu_lastselected = 0;
  2914.  
  2915.  
  2916.     if (selected == -1)
  2917.         sel = menu_lastselected;
  2918.     else sel = selected - 1;
  2919.  
  2920.     if (sel > SEL_MASK)
  2921.     {
  2922.         switch (menu_action[sel & SEL_MASK])
  2923.         {
  2924.             case UI_SWITCH:
  2925.                 res = setdipswitches(bitmap, sel >> SEL_BITS);
  2926.                 break;
  2927.             case UI_DEFCODE:
  2928.                 res = setdefcodesettings(bitmap, sel >> SEL_BITS);
  2929.                 break;
  2930.             case UI_CODE:
  2931.                 res = setcodesettings(bitmap, sel >> SEL_BITS);
  2932.                 break;
  2933.             case UI_ANALOG:
  2934.                 res = settraksettings(bitmap, sel >> SEL_BITS);
  2935.                 break;
  2936.             case UI_CALIBRATE:
  2937.                 res = calibratejoysticks(bitmap, sel >> SEL_BITS);
  2938.                 break;
  2939. #ifndef MESS
  2940.             case UI_STATS:
  2941.                 res = mame_stats(bitmap, sel >> SEL_BITS);
  2942.                 break;
  2943.             case UI_GAMEINFO:
  2944.                 res = displaygameinfo(bitmap, sel >> SEL_BITS);
  2945.                 break;
  2946. #endif
  2947. #ifdef MESS
  2948.             case UI_IMAGEINFO:
  2949.                 res = displayimageinfo(bitmap, sel >> SEL_BITS);
  2950.                 break;
  2951.             case UI_FILEMANAGER:
  2952.                 res = filemanager(bitmap, sel >> SEL_BITS);
  2953.                 break;
  2954.             case UI_TAPECONTROL:
  2955.                 res = tapecontrol(bitmap, sel >> SEL_BITS);
  2956.                 break;
  2957. #endif
  2958.             case UI_HISTORY:
  2959.                 res = displayhistory(bitmap, sel >> SEL_BITS);
  2960.                 break;
  2961.             case UI_CHEAT:
  2962.                 res = cheat_menu(bitmap, sel >> SEL_BITS);
  2963.                 break;
  2964. #ifndef NEOFREE
  2965. #ifndef TINY_COMPILE
  2966.             case UI_MEMCARD:
  2967.                 res = memcard_menu(bitmap, sel >> SEL_BITS);
  2968.                 break;
  2969. #endif
  2970. #endif
  2971.         }
  2972.  
  2973.         if (res == -1)
  2974.         {
  2975.             menu_lastselected = sel;
  2976.             sel = -1;
  2977.         }
  2978.         else
  2979.             sel = (sel & SEL_MASK) | (res << SEL_BITS);
  2980.  
  2981.         return sel + 1;
  2982.     }
  2983.  
  2984.  
  2985.     ui_displaymenu(bitmap,menu_item,0,0,sel,0);
  2986.  
  2987.     if (input_ui_pressed_repeat(IPT_UI_DOWN,8))
  2988.         sel = (sel + 1) % menu_total;
  2989.  
  2990.     if (input_ui_pressed_repeat(IPT_UI_UP,8))
  2991.         sel = (sel + menu_total - 1) % menu_total;
  2992.  
  2993.     if (input_ui_pressed(IPT_UI_SELECT))
  2994.     {
  2995.         switch (menu_action[sel])
  2996.         {
  2997.             case UI_SWITCH:
  2998.             case UI_DEFCODE:
  2999.             case UI_CODE:
  3000.             case UI_ANALOG:
  3001.             case UI_CALIBRATE:
  3002.             #ifndef MESS
  3003.             case UI_STATS:
  3004.             case UI_GAMEINFO:
  3005.             #else
  3006.             case UI_GAMEINFO:
  3007.             case UI_IMAGEINFO:
  3008.             case UI_FILEMANAGER:
  3009.             case UI_TAPECONTROL:
  3010.             #endif
  3011.             case UI_HISTORY:
  3012.             case UI_CHEAT:
  3013.             case UI_MEMCARD:
  3014.                 sel |= 1 << SEL_BITS;
  3015.                 /* tell updatescreen() to clean after us */
  3016.                 need_to_clear_bitmap = 1;
  3017.                 break;
  3018.  
  3019.             case UI_RESET:
  3020.                 machine_reset();
  3021.                 break;
  3022.  
  3023.             case UI_EXIT:
  3024.                 menu_lastselected = 0;
  3025.                 sel = -1;
  3026.                 break;
  3027.         }
  3028.     }
  3029.  
  3030.     if (input_ui_pressed(IPT_UI_CANCEL) ||
  3031.             input_ui_pressed(IPT_UI_CONFIGURE))
  3032.     {
  3033.         menu_lastselected = sel;
  3034.         sel = -1;
  3035.     }
  3036.  
  3037.     if (sel == -1)
  3038.     {
  3039.         /* tell updatescreen() to clean after us */
  3040.         need_to_clear_bitmap = 1;
  3041.     }
  3042.  
  3043.     return sel + 1;
  3044. }
  3045.  
  3046.  
  3047.  
  3048. /*********************************************************************
  3049.  
  3050.   start of On Screen Display handling
  3051.  
  3052. *********************************************************************/
  3053.  
  3054. static void displayosd(struct osd_bitmap *bitmap,const char *text,int percentage,int default_percentage)
  3055. {
  3056.     struct DisplayText dt[2];
  3057.     int avail;
  3058.  
  3059.  
  3060.     avail = (Machine->uiwidth / Machine->uifontwidth) * 19 / 20;
  3061.  
  3062.     ui_drawbox(bitmap,(Machine->uiwidth - Machine->uifontwidth * avail) / 2,
  3063.             (Machine->uiheight - 7*Machine->uifontheight/2),
  3064.             avail * Machine->uifontwidth,
  3065.             3*Machine->uifontheight);
  3066.  
  3067.     avail--;
  3068.  
  3069.     drawbar(bitmap,(Machine->uiwidth - Machine->uifontwidth * avail) / 2,
  3070.             (Machine->uiheight - 3*Machine->uifontheight),
  3071.             avail * Machine->uifontwidth,
  3072.             Machine->uifontheight,
  3073.             percentage,default_percentage);
  3074.  
  3075.     dt[0].text = text;
  3076.     dt[0].color = UI_COLOR_NORMAL;
  3077.     dt[0].x = (Machine->uiwidth - Machine->uifontwidth * strlen(text)) / 2;
  3078.     dt[0].y = (Machine->uiheight - 2*Machine->uifontheight) + 2;
  3079.     dt[1].text = 0; /* terminate array */
  3080.     displaytext(bitmap,dt,0,0);
  3081. }
  3082.  
  3083.  
  3084.  
  3085. static void onscrd_volume(struct osd_bitmap *bitmap,int increment,int arg)
  3086. {
  3087.     char buf[20];
  3088.     int attenuation;
  3089.  
  3090.     if (increment)
  3091.     {
  3092.         attenuation = osd_get_mastervolume();
  3093.         attenuation += increment;
  3094.         if (attenuation > 0) attenuation = 0;
  3095.         if (attenuation < -32) attenuation = -32;
  3096.         osd_set_mastervolume(attenuation);
  3097.     }
  3098.     attenuation = osd_get_mastervolume();
  3099.  
  3100.     sprintf(buf,"%s %3ddB", ui_getstring (UI_volume), attenuation);
  3101.     displayosd(bitmap,buf,100 * (attenuation + 32) / 32,100);
  3102. }
  3103.  
  3104. static void onscrd_mixervol(struct osd_bitmap *bitmap,int increment,int arg)
  3105. {
  3106.     static void *driver = 0;
  3107.     char buf[40];
  3108.     int volume,ch;
  3109.     int doallchannels = 0;
  3110.     int proportional = 0;
  3111.  
  3112.  
  3113.     if (code_pressed(KEYCODE_LSHIFT) || code_pressed(KEYCODE_RSHIFT))
  3114.         doallchannels = 1;
  3115.     if (!code_pressed(KEYCODE_LCONTROL) && !code_pressed(KEYCODE_RCONTROL))
  3116.         increment *= 5;
  3117.     if (code_pressed(KEYCODE_LALT) || code_pressed(KEYCODE_RALT))
  3118.         proportional = 1;
  3119.  
  3120.     if (increment)
  3121.     {
  3122.         if (proportional)
  3123.         {
  3124.             static int old_vol[MIXER_MAX_CHANNELS];
  3125.             float ratio = 1.0;
  3126.             int overflow = 0;
  3127.  
  3128.             if (driver != Machine->drv)
  3129.             {
  3130.                 driver = (void *)Machine->drv;
  3131.                 for (ch = 0; ch < MIXER_MAX_CHANNELS; ch++)
  3132.                     old_vol[ch] = mixer_get_mixing_level(ch);
  3133.             }
  3134.  
  3135.             volume = mixer_get_mixing_level(arg);
  3136.             if (old_vol[arg])
  3137.                 ratio = (float)(volume + increment) / (float)old_vol[arg];
  3138.  
  3139.             for (ch = 0; ch < MIXER_MAX_CHANNELS; ch++)
  3140.             {
  3141.                 if (mixer_get_name(ch) != 0)
  3142.                 {
  3143.                     volume = ratio * old_vol[ch];
  3144.                     if (volume < 0 || volume > 100)
  3145.                         overflow = 1;
  3146.                 }
  3147.             }
  3148.  
  3149.             if (!overflow)
  3150.             {
  3151.                 for (ch = 0; ch < MIXER_MAX_CHANNELS; ch++)
  3152.                 {
  3153.                     volume = ratio * old_vol[ch];
  3154.                     mixer_set_mixing_level(ch,volume);
  3155.                 }
  3156.             }
  3157.         }
  3158.         else
  3159.         {
  3160.             driver = 0; /* force reset of saved volumes */
  3161.  
  3162.             volume = mixer_get_mixing_level(arg);
  3163.             volume += increment;
  3164.             if (volume > 100) volume = 100;
  3165.             if (volume < 0) volume = 0;
  3166.  
  3167.             if (doallchannels)
  3168.             {
  3169.                 for (ch = 0;ch < MIXER_MAX_CHANNELS;ch++)
  3170.                     mixer_set_mixing_level(ch,volume);
  3171.             }
  3172.             else
  3173.                 mixer_set_mixing_level(arg,volume);
  3174.         }
  3175.     }
  3176.     volume = mixer_get_mixing_level(arg);
  3177.  
  3178.     if (proportional)
  3179.         sprintf(buf,"%s %s %3d%%", ui_getstring (UI_allchannels), ui_getstring (UI_relative), volume);
  3180.     else if (doallchannels)
  3181.         sprintf(buf,"%s %s %3d%%", ui_getstring (UI_allchannels), ui_getstring (UI_volume), volume);
  3182.     else
  3183.         sprintf(buf,"%s %s %3d%%",mixer_get_name(arg), ui_getstring (UI_volume), volume);
  3184.     displayosd(bitmap,buf,volume,mixer_get_default_mixing_level(arg));
  3185. }
  3186.  
  3187. static void onscrd_brightness(struct osd_bitmap *bitmap,int increment,int arg)
  3188. {
  3189.     char buf[20];
  3190.     int brightness;
  3191.  
  3192.  
  3193.     if (increment)
  3194.     {
  3195.         brightness = osd_get_brightness();
  3196.         brightness += 5 * increment;
  3197.         if (brightness < 0) brightness = 0;
  3198.         if (brightness > 100) brightness = 100;
  3199.         osd_set_brightness(brightness);
  3200.     }
  3201.     brightness = osd_get_brightness();
  3202.  
  3203.     sprintf(buf,"%s %3d%%", ui_getstring (UI_brightness), brightness);
  3204.     displayosd(bitmap,buf,brightness,100);
  3205. }
  3206.  
  3207. static void onscrd_gamma(struct osd_bitmap *bitmap,int increment,int arg)
  3208. {
  3209.     char buf[20];
  3210.     float gamma_correction;
  3211.  
  3212.     if (increment)
  3213.     {
  3214.         gamma_correction = osd_get_gamma();
  3215.  
  3216.         gamma_correction += 0.05 * increment;
  3217.         if (gamma_correction < 0.5) gamma_correction = 0.5;
  3218.         if (gamma_correction > 2.0) gamma_correction = 2.0;
  3219.  
  3220.         osd_set_gamma(gamma_correction);
  3221.     }
  3222.     gamma_correction = osd_get_gamma();
  3223.  
  3224.     sprintf(buf,"%s %1.2f", ui_getstring (UI_gamma), gamma_correction);
  3225.     displayosd(bitmap,buf,100*(gamma_correction-0.5)/(2.0-0.5),100*(1.0-0.5)/(2.0-0.5));
  3226. }
  3227.  
  3228. static void onscrd_vector_intensity(struct osd_bitmap *bitmap,int increment,int arg)
  3229. {
  3230.     char buf[30];
  3231.     float intensity_correction;
  3232.  
  3233.     if (increment)
  3234.     {
  3235.         intensity_correction = vector_get_intensity();
  3236.  
  3237.         intensity_correction += 0.05 * increment;
  3238.         if (intensity_correction < 0.5) intensity_correction = 0.5;
  3239.         if (intensity_correction > 3.0) intensity_correction = 3.0;
  3240.  
  3241.         vector_set_intensity(intensity_correction);
  3242.     }
  3243.     intensity_correction = vector_get_intensity();
  3244.  
  3245.     sprintf(buf,"%s %1.2f", ui_getstring (UI_vectorintensity), intensity_correction);
  3246.     displayosd(bitmap,buf,100*(intensity_correction-0.5)/(3.0-0.5),100*(1.5-0.5)/(3.0-0.5));
  3247. }
  3248.  
  3249.  
  3250. static void onscrd_overclock(struct osd_bitmap *bitmap,int increment,int arg)
  3251. {
  3252.     char buf[30];
  3253.     double overclock;
  3254.     int cpu, doallcpus = 0, oc;
  3255.  
  3256.     if (code_pressed(KEYCODE_LSHIFT) || code_pressed(KEYCODE_RSHIFT))
  3257.         doallcpus = 1;
  3258.     if (!code_pressed(KEYCODE_LCONTROL) && !code_pressed(KEYCODE_RCONTROL))
  3259.         increment *= 5;
  3260.     if( increment )
  3261.     {
  3262.         overclock = timer_get_overclock(arg);
  3263.         overclock += 0.01 * increment;
  3264.         if (overclock < 0.01) overclock = 0.01;
  3265.         if (overclock > 2.0) overclock = 2.0;
  3266.         if( doallcpus )
  3267.             for( cpu = 0; cpu < cpu_gettotalcpu(); cpu++ )
  3268.                 timer_set_overclock(cpu, overclock);
  3269.         else
  3270.             timer_set_overclock(arg, overclock);
  3271.     }
  3272.  
  3273.     oc = 100 * timer_get_overclock(arg) + 0.5;
  3274.  
  3275.     if( doallcpus )
  3276.         sprintf(buf,"%s %s %3d%%", ui_getstring (UI_allcpus), ui_getstring (UI_overclock), oc);
  3277.     else
  3278.         sprintf(buf,"%s %s%d %3d%%", ui_getstring (UI_overclock), ui_getstring (UI_cpu), arg, oc);
  3279.     displayosd(bitmap,buf,oc/2,100/2);
  3280. }
  3281.  
  3282. #define MAX_OSD_ITEMS 30
  3283. static void (*onscrd_fnc[MAX_OSD_ITEMS])(struct osd_bitmap *bitmap,int increment,int arg);
  3284. static int onscrd_arg[MAX_OSD_ITEMS];
  3285. static int onscrd_total_items;
  3286.  
  3287. static void onscrd_init(void)
  3288. {
  3289.     int item,ch;
  3290.  
  3291.  
  3292.     item = 0;
  3293.  
  3294.     onscrd_fnc[item] = onscrd_volume;
  3295.     onscrd_arg[item] = 0;
  3296.     item++;
  3297.  
  3298.     for (ch = 0;ch < MIXER_MAX_CHANNELS;ch++)
  3299.     {
  3300.         if (mixer_get_name(ch) != 0)
  3301.         {
  3302.             onscrd_fnc[item] = onscrd_mixervol;
  3303.             onscrd_arg[item] = ch;
  3304.             item++;
  3305.         }
  3306.     }
  3307.  
  3308.     if (options.cheat)
  3309.     {
  3310.         for (ch = 0;ch < cpu_gettotalcpu();ch++)
  3311.         {
  3312.             onscrd_fnc[item] = onscrd_overclock;
  3313.             onscrd_arg[item] = ch;
  3314.             item++;
  3315.         }
  3316.     }
  3317.  
  3318.     onscrd_fnc[item] = onscrd_brightness;
  3319.     onscrd_arg[item] = 0;
  3320.     item++;
  3321.  
  3322.     onscrd_fnc[item] = onscrd_gamma;
  3323.     onscrd_arg[item] = 0;
  3324.     item++;
  3325.  
  3326.     if (Machine->drv->video_attributes & VIDEO_TYPE_VECTOR)
  3327.     {
  3328.         onscrd_fnc[item] = onscrd_vector_intensity;
  3329.         onscrd_arg[item] = 0;
  3330.         item++;
  3331.     }
  3332.  
  3333.     onscrd_total_items = item;
  3334. }
  3335.  
  3336. static int on_screen_display(struct osd_bitmap *bitmap, int selected)
  3337. {
  3338.     int increment,sel;
  3339.     static int lastselected = 0;
  3340.  
  3341.  
  3342.     if (selected == -1)
  3343.         sel = lastselected;
  3344.     else sel = selected - 1;
  3345.  
  3346.     increment = 0;
  3347.     if (input_ui_pressed_repeat(IPT_UI_LEFT,8))
  3348.         increment = -1;
  3349.     if (input_ui_pressed_repeat(IPT_UI_RIGHT,8))
  3350.         increment = 1;
  3351.     if (input_ui_pressed_repeat(IPT_UI_DOWN,8))
  3352.         sel = (sel + 1) % onscrd_total_items;
  3353.     if (input_ui_pressed_repeat(IPT_UI_UP,8))
  3354.         sel = (sel + onscrd_total_items - 1) % onscrd_total_items;
  3355.  
  3356.     (*onscrd_fnc[sel])(bitmap,increment,onscrd_arg[sel]);
  3357.  
  3358.     lastselected = sel;
  3359.  
  3360.     if (input_ui_pressed(IPT_UI_ON_SCREEN_DISPLAY))
  3361.     {
  3362.         sel = -1;
  3363.  
  3364.         /* tell updatescreen() to clean after us */
  3365.         need_to_clear_bitmap = 1;
  3366.     }
  3367.  
  3368.     return sel + 1;
  3369. }
  3370.  
  3371. /*********************************************************************
  3372.  
  3373.   end of On Screen Display handling
  3374.  
  3375. *********************************************************************/
  3376.  
  3377.  
  3378. static void displaymessage(struct osd_bitmap *bitmap,const char *text)
  3379. {
  3380.     struct DisplayText dt[2];
  3381.     int avail;
  3382.  
  3383.  
  3384.     if (Machine->uiwidth < Machine->uifontwidth * strlen(text))
  3385.     {
  3386.         ui_displaymessagewindow(bitmap,text);
  3387.         return;
  3388.     }
  3389.  
  3390.     avail = strlen(text)+2;
  3391.  
  3392.     ui_drawbox(bitmap,(Machine->uiwidth - Machine->uifontwidth * avail) / 2,
  3393.             Machine->uiheight - 3*Machine->uifontheight,
  3394.             avail * Machine->uifontwidth,
  3395.             2*Machine->uifontheight);
  3396.  
  3397.     dt[0].text = text;
  3398.     dt[0].color = UI_COLOR_NORMAL;
  3399.     dt[0].x = (Machine->uiwidth - Machine->uifontwidth * strlen(text)) / 2;
  3400.     dt[0].y = Machine->uiheight - 5*Machine->uifontheight/2;
  3401.     dt[1].text = 0; /* terminate array */
  3402.     displaytext(bitmap,dt,0,0);
  3403. }
  3404.  
  3405.  
  3406. static char messagetext[80];
  3407. static int messagecounter;
  3408.  
  3409. void CLIB_DECL usrintf_showmessage(const char *text,...)
  3410. {
  3411.     va_list arg;
  3412.     va_start(arg,text);
  3413.     vsprintf(messagetext,text,arg);
  3414.     va_end(arg);
  3415.     messagecounter = 2 * Machine->drv->frames_per_second;
  3416. }
  3417.  
  3418.  
  3419.  
  3420.  
  3421. int handle_user_interface(struct osd_bitmap *bitmap)
  3422. {
  3423.     static int show_profiler;
  3424. #ifdef MAME_DEBUG
  3425.     static int show_total_colors;
  3426. #endif
  3427.  
  3428. #ifdef MESS
  3429. if (Machine->gamedrv->flags & GAME_COMPUTER)
  3430. {
  3431.     static int ui_active = 0, ui_toggle_key = 0;
  3432.     static int ui_display_count = 4 * 60;
  3433.  
  3434.     if( input_ui_pressed(IPT_UI_TOGGLE_UI) )
  3435.     {
  3436.         if( !ui_toggle_key )
  3437.         {
  3438.             ui_toggle_key = 1;
  3439.             ui_active = !ui_active;
  3440.             ui_display_count = 4 * 60;
  3441.             bitmap_dirty = 1;
  3442.          }
  3443.     }
  3444.     else
  3445.     {
  3446.         ui_toggle_key = 0;
  3447.     }
  3448.  
  3449.     if( ui_active )
  3450.     {
  3451.         if( ui_display_count > 0 )
  3452.         {
  3453.             char text[] = "KBD: UI  (ScrLock)";
  3454.             int x, x0 = Machine->uiwidth - sizeof(text) * Machine->uifont->width - 2;
  3455.             int y0 = Machine->uiymin + Machine->uiheight - Machine->uifont->height - 2;
  3456.             for( x = 0; text[x]; x++ )
  3457.             {
  3458.                 drawgfx(bitmap,
  3459.                     Machine->uifont,text[x],0,0,0,
  3460.                     x0+x*Machine->uifont->width,
  3461.                     y0,0,TRANSPARENCY_NONE,0);
  3462.             }
  3463.             if( --ui_display_count == 0 )
  3464.                 bitmap_dirty = 1;
  3465.         }
  3466.     }
  3467.     else
  3468.     {
  3469.         if( ui_display_count > 0 )
  3470.         {
  3471.             char text[] = "KBD: EMU (ScrLock)";
  3472.             int x, x0 = Machine->uiwidth - sizeof(text) * Machine->uifont->width - 2;
  3473.             int y0 = Machine->uiymin + Machine->uiheight - Machine->uifont->height - 2;
  3474.             for( x = 0; text[x]; x++ )
  3475.             {
  3476.                 drawgfx(bitmap,
  3477.                     Machine->uifont,text[x],0,0,0,
  3478.                     x0+x*Machine->uifont->width,
  3479.                     y0,0,TRANSPARENCY_NONE,0);
  3480.             }
  3481.             if( --ui_display_count == 0 )
  3482.                 bitmap_dirty = 1;
  3483.         }
  3484.         return 0;
  3485.     }
  3486. }
  3487. #endif
  3488.  
  3489.     /* if the user pressed F12, save the screen to a file */
  3490.     if (input_ui_pressed(IPT_UI_SNAPSHOT))
  3491.         osd_save_snapshot();
  3492.  
  3493.     /* This call is for the cheat, it must be called once a frame */
  3494.     if (options.cheat) DoCheat(bitmap);
  3495.  
  3496.     /* if the user pressed ESC, stop the emulation */
  3497.     /* but don't quit if the setup menu is on screen */
  3498.     if (setup_selected == 0 && input_ui_pressed(IPT_UI_CANCEL))
  3499.         return 1;
  3500.  
  3501.     if (setup_selected == 0 && input_ui_pressed(IPT_UI_CONFIGURE))
  3502.     {
  3503.         setup_selected = -1;
  3504.         if (osd_selected != 0)
  3505.         {
  3506.             osd_selected = 0;    /* disable on screen display */
  3507.             /* tell updatescreen() to clean after us */
  3508.             need_to_clear_bitmap = 1;
  3509.         }
  3510.     }
  3511.     if (setup_selected != 0) setup_selected = setup_menu(bitmap, setup_selected);
  3512.  
  3513.     if (!mame_debug && osd_selected == 0 && input_ui_pressed(IPT_UI_ON_SCREEN_DISPLAY))
  3514.     {
  3515.         osd_selected = -1;
  3516.         if (setup_selected != 0)
  3517.         {
  3518.             setup_selected = 0; /* disable setup menu */
  3519.             /* tell updatescreen() to clean after us */
  3520.             need_to_clear_bitmap = 1;
  3521.         }
  3522.     }
  3523.     if (osd_selected != 0) osd_selected = on_screen_display(bitmap, osd_selected);
  3524.  
  3525.  
  3526. #if 0
  3527.     if (keyboard_pressed_memory(KEYCODE_BACKSPACE))
  3528.     {
  3529.         if (jukebox_selected != -1)
  3530.         {
  3531.             jukebox_selected = -1;
  3532.             cpu_halt(0,1);
  3533.         }
  3534.         else
  3535.         {
  3536.             jukebox_selected = 0;
  3537.             cpu_halt(0,0);
  3538.         }
  3539.     }
  3540.  
  3541.     if (jukebox_selected != -1)
  3542.     {
  3543.         char buf[40];
  3544.         watchdog_reset_w(0,0);
  3545.         if (keyboard_pressed_memory(KEYCODE_LCONTROL))
  3546.         {
  3547. #include "cpu/z80/z80.h"
  3548.             soundlatch_w(0,jukebox_selected);
  3549.             cpu_cause_interrupt(1,Z80_NMI_INT);
  3550.         }
  3551.         if (input_ui_pressed_repeat(IPT_UI_RIGHT,8))
  3552.         {
  3553.             jukebox_selected = (jukebox_selected + 1) & 0xff;
  3554.         }
  3555.         if (input_ui_pressed_repeat(IPT_UI_LEFT,8))
  3556.         {
  3557.             jukebox_selected = (jukebox_selected - 1) & 0xff;
  3558.         }
  3559.         if (input_ui_pressed_repeat(IPT_UI_UP,8))
  3560.         {
  3561.             jukebox_selected = (jukebox_selected + 16) & 0xff;
  3562.         }
  3563.         if (input_ui_pressed_repeat(IPT_UI_DOWN,8))
  3564.         {
  3565.             jukebox_selected = (jukebox_selected - 16) & 0xff;
  3566.         }
  3567.         sprintf(buf,"sound cmd %02x",jukebox_selected);
  3568.         displaymessage(buf);
  3569.     }
  3570. #endif
  3571.  
  3572.  
  3573.     /* if the user pressed F3, reset the emulation */
  3574.     if (input_ui_pressed(IPT_UI_RESET_MACHINE))
  3575.         machine_reset();
  3576.  
  3577.  
  3578.     if (single_step || input_ui_pressed(IPT_UI_PAUSE)) /* pause the game */
  3579.     {
  3580. /*        osd_selected = 0;       disable on screen display, since we are going   */
  3581.                             /* to change parameters affected by it */
  3582.  
  3583.         if (single_step == 0)
  3584.         {
  3585.             osd_sound_enable(0);
  3586.             osd_pause(1);
  3587.         }
  3588.  
  3589.         while (!input_ui_pressed(IPT_UI_PAUSE))
  3590.         {
  3591. #ifdef MAME_NET
  3592.             osd_net_sync();
  3593. #endif /* MAME_NET */
  3594.             profiler_mark(PROFILER_VIDEO);
  3595.             if (osd_skip_this_frame() == 0)
  3596.             {
  3597.                 if (need_to_clear_bitmap || bitmap_dirty)
  3598.                 {
  3599.                     osd_clearbitmap(bitmap);
  3600.                     need_to_clear_bitmap = 0;
  3601.                     draw_screen(bitmap_dirty);
  3602.                     bitmap_dirty = 0;
  3603.                 }
  3604. #ifdef MAME_DEBUG
  3605. /* keep calling vh_screenrefresh() while paused so we can stuff */
  3606. /* debug code in there */
  3607. draw_screen(bitmap_dirty);
  3608. #endif
  3609.             }
  3610.             profiler_mark(PROFILER_END);
  3611.  
  3612.             if (input_ui_pressed(IPT_UI_SNAPSHOT))
  3613.                 osd_save_snapshot();
  3614.  
  3615.             if (setup_selected == 0 && input_ui_pressed(IPT_UI_CANCEL))
  3616.                 return 1;
  3617.  
  3618.             if (setup_selected == 0 && input_ui_pressed(IPT_UI_CONFIGURE))
  3619.             {
  3620.                 setup_selected = -1;
  3621.                 if (osd_selected != 0)
  3622.                 {
  3623.                     osd_selected = 0;    /* disable on screen display */
  3624.                     /* tell updatescreen() to clean after us */
  3625.                     need_to_clear_bitmap = 1;
  3626.                 }
  3627.             }
  3628.             if (setup_selected != 0) setup_selected = setup_menu(bitmap, setup_selected);
  3629.  
  3630.             if (!mame_debug && osd_selected == 0 && input_ui_pressed(IPT_UI_ON_SCREEN_DISPLAY))
  3631.             {
  3632.                 osd_selected = -1;
  3633.                 if (setup_selected != 0)
  3634.                 {
  3635.                     setup_selected = 0; /* disable setup menu */
  3636.                     /* tell updatescreen() to clean after us */
  3637.                     need_to_clear_bitmap = 1;
  3638.                 }
  3639.             }
  3640.             if (osd_selected != 0) osd_selected = on_screen_display(bitmap, osd_selected);
  3641.  
  3642.             /* show popup message if any */
  3643.             if (messagecounter > 0) displaymessage(bitmap, messagetext);
  3644.  
  3645.             update_video_and_audio();
  3646.             osd_poll_joysticks();
  3647.         }
  3648.  
  3649.         if (code_pressed(KEYCODE_LSHIFT) || code_pressed(KEYCODE_RSHIFT))
  3650.             single_step = 1;
  3651.         else
  3652.         {
  3653.             single_step = 0;
  3654.             osd_pause(0);
  3655.             osd_sound_enable(1);
  3656.         }
  3657.     }
  3658.  
  3659.  
  3660.     /* show popup message if any */
  3661.     if (messagecounter > 0)
  3662.     {
  3663.         displaymessage(bitmap, messagetext);
  3664.  
  3665.         if (--messagecounter == 0)
  3666.             /* tell updatescreen() to clean after us */
  3667.             need_to_clear_bitmap = 1;
  3668.     }
  3669.  
  3670.  
  3671.     if (input_ui_pressed(IPT_UI_SHOW_PROFILER))
  3672.     {
  3673.         show_profiler ^= 1;
  3674.         if (show_profiler)
  3675.             profiler_start();
  3676.         else
  3677.         {
  3678.             profiler_stop();
  3679.             /* tell updatescreen() to clean after us */
  3680.             need_to_clear_bitmap = 1;
  3681.         }
  3682.     }
  3683. #ifdef MAME_DEBUG
  3684.     if (input_ui_pressed(IPT_UI_SHOW_COLORS))
  3685.     {
  3686.         show_total_colors ^= 1;
  3687.         if (show_total_colors == 0)
  3688.             /* tell updatescreen() to clean after us */
  3689.             need_to_clear_bitmap = 1;
  3690.     }
  3691.     if (show_total_colors) showtotalcolors(bitmap);
  3692. #endif
  3693.  
  3694.     if (show_profiler) profiler_show(bitmap);
  3695.  
  3696.  
  3697.     /* if the user pressed F4, show the character set */
  3698.     if (input_ui_pressed(IPT_UI_SHOW_GFX))
  3699.     {
  3700.         osd_sound_enable(0);
  3701.  
  3702.         showcharset(bitmap);
  3703.  
  3704.         osd_sound_enable(1);
  3705.     }
  3706.  
  3707.     return 0;
  3708. }
  3709.  
  3710.  
  3711. void init_user_interface(void)
  3712. {
  3713.     extern int snapno;    /* in common.c */
  3714.  
  3715.     snapno = 0; /* reset snapshot counter */
  3716.  
  3717.     setup_menu_init();
  3718.     setup_selected = 0;
  3719.  
  3720.     onscrd_init();
  3721.     osd_selected = 0;
  3722.  
  3723.     jukebox_selected = -1;
  3724.  
  3725.     single_step = 0;
  3726.  
  3727.     orientation_count = 0;
  3728. }
  3729.  
  3730. int onscrd_active(void)
  3731. {
  3732.     return osd_selected;
  3733. }
  3734.  
  3735. int setup_active(void)
  3736. {
  3737.     return setup_selected;
  3738. }
  3739.  
  3740.